为什么执行ping命令时不需要root权限? 怎样让进程具有root权限?

本文介绍如何通过设置SUID权限使普通用户的程序拥有Root权限,并提供了一个具体的编程示例。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

     最近遇到一个问题, 需要让普通用户执行程序时具有root权限, 怎么办呢?

     我们来看看ping, 它采用了raw socket, 需要root权限, 但是, 我们平常执行root命令的时候, 没有加sudo啊, 来探个究竟:

ubuntu@VM-0-15-ubuntu:~/taoge/raw_soc$ ll `which ping`
-rwsr-xr-x 1 root root 44168 May  8  2014 /bin/ping*
ubuntu@VM-0-15-ubuntu:~/taoge/raw_soc$ 

     可以看到, 可执行程序二进制文件ping的owner是root, 且是rws的, 注意这个s

     APUE说:若文件的所有者是超级用户,而且设置了该文件的设置用户位(suid),然后该程序由一个进程执行时,则该进程具有超级用户特权。

 

    所以, 我们来模仿ping的方式。 程序如下:

#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <linux/if_ether.h>
#include <stdlib.h>
#include <arpa/inet.h>

int main()
{
	printf("main is running\n");

    int iSock, nRead, iProtocol;        
    char buffer[4096] = {0};
    char  *ethhead, *iphead, *tcphead, *udphead, *icmphead, *p;
	
	if((iSock = socket(PF_PACKET, SOCK_RAW, htons(ETH_P_IP))) < 0)
    {
        printf("create iSocket error, check root\n");  // 需要root权限
        return 1;
    }
	        
	while(1) 
	{
		nRead = recvfrom(iSock, buffer, 2048, 0, NULL, NULL);  
		/*
			以太网帧头 14
			ip头       20
			udp头      8
			总共42字节(最少)
		*/
		if(nRead < 42) 
		{
			printf("packet error\n");
			continue;
		}
	        	
		int n = 0XFF;
		char szVisBuf[1024] = {0};
		for(unsigned int i = 0; i < nRead; ++i)
		{
			char szTmp[3] = {0};
			sprintf(szTmp, "%02x", buffer[i]&n);
			strcat(szVisBuf, szTmp);
		}
			
		
		ethhead = buffer;
		p = ethhead;
		
		iphead = ethhead + 14;  
		p = iphead + 12;

		char szIps[128] = {0};
		snprintf(szIps, sizeof(szIps), "IP: %d.%d.%d.%d => %d.%d.%d.%d",
			p[0]&n, p[1]&n, p[2]&n, p[3]&n,
			p[4]&n, p[5]&n, p[6]&n, p[7]&n);
		iProtocol = (iphead + 9)[0];
		p = iphead + 20;
		
		
		unsigned int iDstPort = (p[2]<<8)&0xff00 | p[3]&n;
		switch(iProtocol)
		{
			case IPPROTO_UDP : 
				if(iDstPort == 8888)
				{
					printf("source port: %u,",(p[0]<<8)&0xff00 |  p[1]&n);
					printf("dest port: %u\n", iDstPort);
					
					printf("%s\n", szIps);	
					printf("%s\n", szVisBuf);
					printf("nRead is %d\n", nRead);	
					
				}
				break;
			case IPPROTO_RAW : 
				printf("raw\n");
				break;
			default:
				break;
		}
	}
}

       再看:

ubuntu@VM-0-15-ubuntu:~/taoge/raw_soc$ g++ server.cpp 
ubuntu@VM-0-15-ubuntu:~/taoge/raw_soc$ ./a.out 
main is running
create iSocket error, check root
ubuntu@VM-0-15-ubuntu:~/taoge/raw_soc$ ll a.out 
-rwxrwxr-x 1 ubuntu ubuntu 9016 Mar  2 22:26 a.out*
ubuntu@VM-0-15-ubuntu:~/taoge/raw_soc$ 
ubuntu@VM-0-15-ubuntu:~/taoge/raw_soc$ 
ubuntu@VM-0-15-ubuntu:~/taoge/raw_soc$ 
ubuntu@VM-0-15-ubuntu:~/taoge/raw_soc$ sudo chown root a.out 
ubuntu@VM-0-15-ubuntu:~/taoge/raw_soc$ sudo chmod u+s a.out 
ubuntu@VM-0-15-ubuntu:~/taoge/raw_soc$ ll a.out 
-rwsrwxr-x 1 root ubuntu 9016 Mar  2 22:26 a.out*
ubuntu@VM-0-15-ubuntu:~/taoge/raw_soc$ 
ubuntu@VM-0-15-ubuntu:~/taoge/raw_soc$ 
ubuntu@VM-0-15-ubuntu:~/taoge/raw_soc$ 
ubuntu@VM-0-15-ubuntu:~/taoge/raw_soc$ ./a.out 
main is running

       结果OK, 可见a.out进程具有了root权限。

       由于进程具有了root权限, 所以操作的时候, 一定要注意安全问题。

 

 

 

 

 

    

<think>我们正在讨论Linux中执行ping命令产生的进程以及如何查找其PID。根据用户的问题,他们想知道ping命令的PID是什么以及如何查找它。结合之前的回答和引用内容,我们可以这样回答: 1. ping命令在运行会产生一个独立的进程,每个ping命令实例都有一个唯一的进程ID(PID)。 2. 查找ping命令的PID可以使用以下方法: - 使用`pidof`命令:`pidof ping` 会返回所有名为"ping"的进程的PID。 - 使用`pgrep`命令:`pgrep ping` 同样可以查找进程名为"ping"的PID。 - 使用`ps`命令:`ps aux | grep ping` 可以列出包含"ping"的进程信息,其中包括PID。 注意:由于可能有多个ping进程在运行,所以这些命令可能会返回多个PID。如果只想返回一个PID,可以使用`pidof -s ping`(仅返回一个)或`pgrep -n ping`(返回最新的)等选项。 另外,引用[1]和[2]提供了使用`pidof`命令的示例和参数说明,我们可以参考这些信息。 同,用户之前的问题中提到了ping命令是单进程单线程的,所以每个ping命令对应一个进程。 因此,回答将包括: - 解释ping命令进程特性(单进程) - 介绍如何查找其PID(使用pidof, pgrep, ps等命令) - 给出具体命令示例 我们还可以生成相关问题,如: 1. 如何结束正在运行的ping进程? 2. 如何查看ping进程的线程信息? 3. 如何让ping命令在后台运行? 4. 如何持续监控某个ping进程的资源使用情况? 5. 多个ping命令运行会有什么影响? 注意:引用[3]是关于使用C语言实现ping命令并处理信号的例子,虽然与当前问题直接相关,但可以说明ping命令内部可能会使用信号(如SIGALRM)来处理超等,但用户的问题主要是关于PID查找,所以我们深入讨论。 现在组织回答:</think>### Linux ping 命令的 PID 查找方法 在 Linux 中执行 `ping` 命令,系统会创建一个**独立的进程**,每个进程都有唯一的进程标识符(PID)。以下是查找 `ping` 命令 PID 的详细方法: #### 一、核心查找方法 1. **`pidof` 命令(推荐)** ```bash pidof ping ``` - 直接返回所有 `ping` 进程的 PID - 示例输出:`12345 67890`(表示两个正在运行的 ping 进程) - 参数说明: - `-s`:仅返回一个 PID(如 `pidof -s ping`) - `-o`:排除指定 PID(如排除 Shell 自身 PID)[^2] 2. **`pgrep` 命令** ```bash pgrep ping ``` - 更灵活的进程查找工具 - 常用参数: - `-l`:显示进程名和 PID(如 `pgrep -l ping`) - `-n`:仅显示最新启动的进程 3. **组合命令** ```bash ps aux | grep [p]ing ``` - 在进程列表中过滤 ping 进程 - 使用 `[p]ing` 避免 grep 自身进程干扰 #### 二、操作示例 ```bash # 启动后台 ping 进程 ping example.com > /dev/null & # 查找 PID $ pidof ping 78901 # 验证进程 $ ps -p 78901 -o pid,comm PID COMMAND 78901 ping ``` #### 三、技术原理 1. **进程创建机制** - 执行 `ping` 通过 `fork()` + `exec()` 创建子进程 - 父子进程关系可通过 `pstree -p` 查看: ``` bash(1000)───ping(78901) ``` 2. **多实例处理** - 同运行多个 `ping` 会生成多个独立进程 - 使用 `pidof ping` 可返回所有 PID 列表 > **注意**:如果使用 `sudo ping`,实际进程名为 `ping`,但权限root。可通过 `ps -ef | grep ping` 查看完整信息。
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值