zoukankan      html  css  js  c++  java
  • Linuxx学习-特殊文件与进程

    具有 SUID/SGID 权限的指令执行状态

    SUID 的权限其实与进程的相关性非常的大!为什么呢?先来看看 SUID 的程序是如何被一般用户 执行,且具有什么特色呢?

    • SUID 权限仅对二进制程序(binary program)有效;
    • 执行者对于该程序需要具有 x 的可执行权限;
    • 本权限仅在执行该程序的过程中有效 (run-time);
    • 执行者将具有该程序拥有者 (owner) 的权限。

    所以说,整个 SUID 的权限会生效是由于『具有该权限的程序被触发』,而我们知道一个程序被触 发会变成进程, 所以啰,执行者可以具有程序拥有者的权限就是在该程序变成进程的那个时候。

    你或许那时候会觉得很奇怪,为啥执行了 passwd 后你就具 有 root 的权限呢?不都是一般使用者执行的吗? 这是因为你在触发 passwd 后,会取得一个新的进 程与 PID,该 PID 产生时透过 SUID 来给予该 PID 特殊的权限设定啦! 我们使用 dmtsai 登入系 统且执行 passwd 后,透过工作控制来理解一下!

    [dmtsai@study ~]$ passwd
    Changing password for user dmtsai.
    Changing password for dmtsai
    (current) UNIX password: <==这里按下 [ctrl]-z 并且按下 [enter] 
    [1]+ Stopped passwd
    
    [dmtsai@study ~]$ pstree -uA 
    systemd-+-ModemManager---2*[{ModemManager}] 
    ....(中间省略)....
    |-sshd---sshd---sshd(dmtsai)---bash-+-passwd(root)
    |                                                          `-pstree
    ....(底下省略)....
    

    从上表的结果我们可以发现,底线的部分是属于 dmtsai 这个一般账号的权限,特殊字体的则是 root 的权限! 但你看到了, passwd 确实是由 bash 衍生出来的!不过就是权限不一样!透过这样的解 析, 你也会比较清楚为何不同程序所产生的权限不同了吧!这是由于『SUID 程序运作过程中产生 的进程』的关系!

    /proc/* 代表的意义

    我们之前提到的所谓的进程都是在内存当中嘛!而内存当中的数据又都是写入到 /proc/* 这个 目录下的,所以啰,我们当然可以直接观察 /proc 这个目录当中的文件! 如果你观察过 /proc 这 个目录的话,应该会发现他有点像这样:

    root@study ~]# ll /proc
    dr-xr-xr-x.  8 root           root               0 Aug  4 18:46 1
    dr-xr-xr-x.  8 root           root               0 Aug  4 18:46 10
    dr-xr-xr-x.  8 root           root               0 Aug  4 18:47 10548
    ....(中間省略)....
    -r--r--r--.  1 root           root               0 Aug  5 17:48 uptime
    -r--r--r--.  1 root           root               0 Aug  5 17:48 version
    -r--------.  1 root           root               0 Aug  5 17:48 vmallocinfo
    -r--r--r--.  1 root           root               0 Aug  5 17:48 vmstat
    -r--r--r--.  1 root           root               0 Aug  5 17:48 zoneinfo
    

    基本上,目前主机上面的各个进程的 PID 都是以目录的型态存在于 /proc 当中。 举例来说,我们 开机所执行的第一支程序 systemd 他的 PID 是 1 , 这个 PID 的所有相关信息都写入在 /proc/1/* 当中!若我们直接观察 PID 为 1 的数据好了,他有点像这样:

    [root@study ~]# ll 
    dr-xr-xr-x. 2 root root 0 Aug  4 19:25 attr
    -rw-r--r--. 1 root root 0 Aug  4 19:25 autogroup
    -r--------. 1 root root 0 Aug  4 19:25 auxv
    -r--r--r--. 1 root root 0 Aug  4 18:46 cgroup
    --w-------. 1 root root 0 Aug  4 19:25 clear_refs
    -r--r--r--. root 0 Aug 4 18:46 cmdline <==就是指令串 
    -r--------. root 0 Aug 4 18:46 environ <==一些环境变量 
    lrwxrwxrwx. root 0 Aug 4 18:46 exe
    ....(以下省略)....
    

    里面的数据还挺多的,不过,比较有趣的其实是两个文件,分别是:

    • cmdline:这个进程被启动的指令串;

    • environ:这个进程的环境变量内容。

    如果你查阅一下 cmdline 的话,就会发现:

    [root@study ~]# cat /proc/1/cmdline
    /usr/lib/systemd/systemd--switched-root--system--deserialize24
    

    就是这个指令、选项与参数启动 systemd 的啦!这还是跟某个特定的 PID 有关的内容呢,如果是针 对整个 Linux 系统相关的参数呢?那就是在 /proc 目录底下的文件啦!相关的文件与对应的内容是 这样的:

    档名 文件内容
    /proc/cmdline 加载 kernel 时所下达的相关指令与参数!查阅此文件,可了解指令是如何启动的!
    /proc/cpuinfo 本机的 CPU 的相关信息,包含频率、类型与运算功能等
    /proc/devices 这个文件记录了系统各个主要装置的主要装置代号,与 mknod 有关呢!
    /proc/filesystems 目前系统已经加载的文件系统啰!
    /proc/interrupts 目前系统上面的 IRQ 分配状态
    /proc/ioports 目前系统上面各个装置所配置的 I/O 地址。
    /proc/kcore 这个就是内存的大小啦!好大对吧!但是不要读他啦!
    /proc/loadavg 还记得 top 以及 uptime 吧?没错!上头的三个平均数值就是记录在此!
    /proc/meminfo 使用 free 列出的内存信息,嘿嘿!在这里也能够查阅到!
    /proc/modules 目前我们的 Linux 已经加载的模块列表,也可以想成是驱动程序啦!
    /proc/mounts 系统已经挂载的数据,就是用 mount 这个指令呼叫出来的数据啦!
    /proc/swaps 到底系统挂加载的内存在哪里?呵呵!使用掉的 partition 就记录在此啦!
    proc/partitions 使用 fdisk -l 会出现目前所有的 partition 吧?在这个文件当中也有纪录喔!
    /proc/uptime 就是用 uptime 的时候,会出现的信息啦!
    /proc/version 核心的版本,就是用 uname -a 显示的内容啦!
    /proc/bus/* 一些总线的装置,还有 USB 的装置也记录在此喔!

    查询已开启文件或已执行进程开启之文件

    • fuser:藉由文件(或文件系统)找出正在使用该文件的进程

    有的时候我想要知道我的进程到底在这次启动过程中开启了多少文件,可以利用 fuser 来观察啦!举 例来说,你如果卸除时发现系统通知:『 device is busy 』,那表示这个文件系统正在忙碌中, 表
    示有某支进程有利用到该文件系统啦!那么你就可以利用 fuser 来追踪啰!fuser 语法有点像这样:

    [root@study ~]# fuser [-umv] [-k [i] [-signal]] file/dir
    选项与参数:
    -u :除了进程的 PID 之外,同时列出该进程的拥有者;
    -m :后面接的那个档名会主动的上提到该文件系统的最顶层,对 umount 不成功很有效! 
    -v :可以列出每个文件与进程还有指令的完整相关性!
    -k :找出使用该文件/目录的 PID ,并试图以 SIGKILL 这个讯号给予该 PID; 
    -i :必须与 -k 配合,在删除 PID 之前会先询问使用者意愿!
    -signal:例如 -1 -15 等等,若不加的话,预设是 SIGKILL (-9) 啰!
    
    范例一:找出目前所在目录的使用 PID/所属账号/权限 为何?
    [root@study ~]# fuser -uv .
                         USER        PID ACCESS COMMAND
    /root:               root      13888 ..c.. (root)bash
                         root      31743 ..c.. (root)bash
    

    结果为『.』底下有两个 PID 分别为 13888, 31743 的进程,该进程属于 root 且指令为 bash 。 比较有趣的是那个 ACCESS 的项目,那个项目代表的意义为:

    • c :此进程在当前的目录下(非次目录);
    • e :可被触发为执行状态;
    • f :是一个被开启的文件;
    • r :代表顶层目录 (root directory);
    • F :该文件被开启了,不过在等待回应中;
    • m :可能为分享的动态函式库;

    那如果你想要查阅某个文件系统底下有多少进程正在占用该文件系统时,那个 -m 的选项就很有帮 助了!让我们来做几个简单的测试,包括实体的文件系统挂载与 /proc 这个虚拟文件系统的内容,看 看有多少的进程对这些挂载点或其他目录的使用状态吧!

    范例二:找到所有使用到 /proc 这个文件系统的进程吧!
    [root@study ~]# fuser -uv /proc
    /proc:               root     kernel mount (root)/proc
                         rtkit       768 .rc.. (rtkit)rtkit-daemon
    # 数据量还不会很多,虽然这个目录很繁忙~没关系!我们可以继续这样作,看看其他的进程!
    
    [root@study ~]# fuser -mvu /proc
                         USER        PID ACCESS COMMAND
    /proc:               root     kernel mount (root)/proc
                         root          1 f.... (root)systemd
                         root          2 ...e. (root)kthreadd
    .....(底下省略).....
    # 有这几支进程在进行 /proc 文件系统的存取喔!这样清楚了吗?    
    
    范例三:找到所有使用到 /home 这个文件系统的进程吧!
    [root@study ~]# echo $$
    31743 # 先确认一下,自己的 bash PID 号码吧!
    [root@study ~]# cd /home
    [root@study home]# fuser -muv .
                         USER        PID ACCESS COMMAND
    /home:               root     kernel mount (root)/home
                         dmtsai    31535 ..c.. (dmtsai)bash
                         root      31571 ..c.. (root)passwd
                         root      31737 ..c.. (root)sudo
                         root      31743 ..c.. (root)bash    # 果然,自己的 PID 在啊!
    [root@study home]# cd ~
    [root@study ~]# umount /home
    umount: /home: target is busy.
            (In some cases useful info about processes that use
             the device is found by lsof(8) or fuser(1))
    # 从 fuser 的结果可以知道,总共有五只 process 在该目录下运作,那即使 root 离开了 /home,
    # 当然还是无法 umount 的!那要怎办?哈哈!可以透过如下方法一个一个删除~
    [root@study ~]# fuser -mki /home
    /home: 31535c 31571c 31737c # 你会发现, PID 跟上面查到的相同!
    Kill process 31535 ? (y/N) # 这里会问你要不要删除!当然不要乱删除啦!通通取消!
    

    既然可以针对整个文件系统,那么能不能仅针对单一文件啊?当然可以啰!看一下底下的案例先:

    范例四:找到 /run 底下属于 FIFO 类型的文件,并且找出存取该文件的进程
    [root@study ~]# find /run -type p
    .....(前面省略).....
    /run/systemd/sessions/165.ref
    /run/systemd/sessions/1.ref
    /run/systemd/sessions/c1.ref # 随便抓个项目!就是这个好了!来测试一下!
    
    [root@study ~]# fuser -uv /run/systemd/sessions/c1.ref
       USER        PID ACCESS COMMAND
    /run/systemd/sessions/c1.ref:
                         root        763 f.... (root)systemd-logind
                         root       5450 F.... (root)gdm-session-wor
    # 通常系统的 FIFO 文件都会放置到 /run 底下,透过这个方式来追踪该文件被存取的 process! 
    # 也能够晓得系统有多忙碌
    

    透过这个 fuser 我们可以找出使用该文件、目录的进程,藉以观察


    • lsof :列出被进程所开启的文件档名

    fuser 是由文件或者装置去找出使用该文件或装置的进程,反过来说,如何查出某个进程开启 或者使用的文件与装置呢?呼呼!那就是使用 lsof 啰~

    [root@study ~]# lsof [-aUu] [+d]
    选项与参数:
    -a :多项数据需要『同时成立』才显示出结果时!
    -U :仅列出 Unix like 系统的 socket 文件类型;
    -u :后面接 username,列出该使用者相关进程所开启的文件; 
    +d :后面接目录,亦即找出某个目录底下已经被开启的文件!
    
    范例一:列出目前系统上面所有已经被开启的文件与装置:
    [root@study ~]# lsof
    COMMAND   PID   TID    USER   FD   TYPE    DEVICE  SIZE/OFF       NODE NAME
    systemd     1          root  cwd    DIR     253,0      4096        128 /
    systemd     1          root  rtd    DIR     253,0      4096        128 /
    systemd     1          root  txt    REG     253,0   1230920     967763 /usr/lib/systemd/systemd
    ....(底下省略)....
    # 注意到了吗?是的,在预设的情况下, lsof 会将目前系统上面已经开启的
    # 文件全部列出来~所以,画面多的吓人啊!您可以注意到,第一个文件 systemd 执行的
    # 地方就在根目录,而根目录,嘿嘿!所在的 inode 也有显示出来喔!
    
    范例二:仅列出关于 root 的所有进程开启的 socket 文件
    [root@study ~]# lsof -u root -a -U
    COMMAND     PID USER   FD   TYPE             DEVICE SIZE/OFF   NODE NAME
    systemd       1 root    3u  unix 0xffff8800b7756580      0t0  13715 socket
    systemd       1 root    7u  unix 0xffff8800b7755a40      0t0   1902 @/org/freedesktop/systemd1/notify
    systemd       1 root    9u  unix 0xffff8800b7756d00      0t0   1903 /run/systemd/private
    .....(中間省略).....
    Xorg       4496 root    1u  unix 0xffff8800ab107480      0t0  25981 @/tmp/.X11-unix/X0
    Xorg       4496 root    3u  unix 0xffff8800ab107840      0t0  25982 /tmp/.X11-unix/X0
    Xorg       4496 root   16u  unix 0xffff8800b7754f00      0t0  25174 @/tmp/.X11-unix/X0
    .....(底下省略).....
    # 注意到那个 -a 吧!如果你分别输入 lsof -u root 及 lsof -U ,会有啥信息? 
    # 使用 lsof -u root -U 及 lsof -u root -a -U ,都不同啦!
    # -a 的用途就是在解决同时需要两个项目都成立时啊! ^_^
    
    范例三:请列出目前系统上面所有的被启动的周边装置
    [root@study ~]# lsof +d /dev
    COMMAND     PID           USER   FD   TYPE             DEVICE SIZE/OFF NODE NAME
    systemd       1           root    0u   CHR                1,3      0t0 1028 /dev/null
    systemd       1           root    1u   CHR                1,3      0t0 1028 /dev/null
    # 看吧!因为装置都在 /dev 里面嘛!所以啰,使用搜寻目录即可啊!
    
    范例四:秀出属于 root 的 bash 这支程序所开启的文件
    root@study ~]# lsof -u root | grep bash
    ksmtuned    781 root  txt    REG    253,0    960384   33867220 /usr/bin/bash
    bash      13888 root  cwd    DIR    253,0      4096   50331777 /root
    bash      13888 root  rtd    DIR    253,0      4096        128 /
    bash      13888 root  txt    REG    253,0    960384   33867220 /usr/bin/bash
    bash      13888 root  mem    REG    253,0 106065056   17331169 /usr/lib/locale/locale-archive
    ....(底下省略)....
    

    • pidof :找出某支正在执行的程序的 PID
    [root@study ~]# pidof [-sx] program_name
    选项与参数:
    -s :仅列出一个 PID 而不列出所有的 PID
    -x :同时列出该 program name 可能的 PPID 那个进程的 PID
    
    范例一:列出目前系统上面 systemd 以及 rsyslogd 这两个程序的 PID
    [root@study ~]# pidof systemd rsyslogd
    1 742
    # 理论上,应该会有两个 PID 才对。上面的显示也是出现了两个 PID 喔。 
    # 分别是 systemd 及 rsyslogd 这两支程序的 PID 啦。
    
  • 相关阅读:
    HDU 3572 Task Schedule(拆点+最大流dinic)
    POJ 1236 Network of Schools(Tarjan缩点)
    HDU 3605 Escape(状压+最大流)
    HDU 1166 敌兵布阵(分块)
    Leetcode 223 Rectangle Area
    Leetcode 219 Contains Duplicate II STL
    Leetcode 36 Valid Sudoku
    Leetcode 88 Merge Sorted Array STL
    Leetcode 160 Intersection of Two Linked Lists 单向链表
    Leetcode 111 Minimum Depth of Binary Tree 二叉树
  • 原文地址:https://www.cnblogs.com/uetucci/p/7745812.html
Copyright © 2011-2022 走看看