《linux 内核完全剖析》 sys.c 代码分析

2024-06-06 10:08

本文主要是介绍《linux 内核完全剖析》 sys.c 代码分析,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

 sys.c 代码分析

 

 

setregid

/** This is done BSD-style, with no consideration of the saved gid, except* that if you set the effective gid, it sets the saved gid too.  This* makes it possible for a setgid program to completely drop its privileges,* which is often a useful assertion to make when you are doing a security* audit over a program.** The general idea is that a program which uses just setregid() will be* 100% compatible with BSD.  A program which uses just setgid() will be* 100% compatible with POSIX w/ Saved ID's.*/
int sys_setregid(int rgid, int egid)//设置real group ID ,effective group ID
{if (rgid>0) {if ((current->gid == rgid) ||suser())//如果当前进程的gid == real group ID 或者拥有超级用户权限,就可以把当前进程的group ID更改为 real Group ID current->gid = rgid;else //否则setregid是不允许的,返回错误值return(-EPERM);}if (egid>0) {if ((current->gid == egid) ||//如果当前进程的gid 或者effective gid 等于egid 或者拥有超级用户权限,则可以修改当前进程的egid和sgid(current->egid == egid) ||suser()) {current->egid = egid;current->sgid = egid;} elsereturn(-EPERM);}return 0;
}


setgid

/** setgid() is implemeneted like SysV w/ SAVED_IDS*/
int sys_setgid(int gid) //设置当前进程的group ID
{if (suser()) //有超级用户权限就可以更改当前进程的gid,egid(effective gid) ,sgid(saved gid)都设置为gidcurrent->gid = current->egid = current->sgid = gid;else if ((gid == current->gid) || (gid == current->sgid))//如果当前进程的sgid 或者gid(current) 等于 gid(传入参数) ,那么把当前进程的effective gid 设置为gidcurrent->egid = gid;elsereturn -EPERM;return 0;
}



 

sys_time

int sys_time(long * tloc) //设置系统时间
{int i;i = CURRENT_TIME;if (tloc) {verify_area(tloc,4);put_fs_long(i,(unsigned long *)tloc);}return i;
}


sys_setreuid

/** Unprivileged users may change the real user id to the effective uid* or vice versa.  (BSD-style)** When you set the effective uid, it sets the saved uid too.  This* makes it possible for a setuid program to completely drop its privileges,* which is often a useful assertion to make when you are doing a security* audit over a program.** The general idea is that a program which uses just setreuid() will be* 100% compatible with BSD.  A program which uses just setuid() will be* 100% compatible with POSIX w/ Saved ID's.*/
int sys_setreuid(int ruid, int euid) //uid == user ID 设置real 和 effective user ID
{int old_ruid = current->uid;if (ruid>0) {if ((current->euid==ruid) ||(old_ruid == ruid) ||suser())current->uid = ruid;elsereturn(-EPERM);}if (euid>0) {if ((old_ruid == euid) ||(current->euid == euid) ||suser()) {current->euid = euid;current->suid = euid;} else {current->uid = old_ruid;return(-EPERM);}}return 0;
}

setuid()


/** setuid() is implemeneted like SysV w/ SAVED_IDS** Note that SAVED_ID's is deficient in that a setuid root program* like sendmail, for example, cannot set its uid to be a normal* user and then switch back, because if you're root, setuid() sets* the saved uid too.  If you don't like this, blame the bright people* in the POSIX commmittee and/or USG.  Note that the BSD-style setreuid()* will allow a root program to temporarily drop privileges and be able to* regain them by swapping the real and effective uid.  */
int sys_setuid(int uid) //设置user ID
{if (suser())current->uid = current->euid = current->suid = uid;else if ((uid == current->uid) || (uid == current->suid))current->euid = uid;elsereturn -EPERM;return(0);
}int sys_stime(long * tptr) //设置系统时间
{if (!suser())return -EPERM;startup_time = get_fs_long((unsigned long *)tptr) - jiffies/HZ;jiffies_offset = 0;return 0;
}

sys_times

int sys_times(struct tms * tbuf) //获取系统时间把内核数据段的数据读到tbuf里去
{if (tbuf) {verify_area(tbuf,sizeof *tbuf);put_fs_long(current->utime,(unsigned long *)&tbuf->tms_utime);put_fs_long(current->stime,(unsigned long *)&tbuf->tms_stime);put_fs_long(current->cutime,(unsigned long *)&tbuf->tms_cutime);put_fs_long(current->cstime,(unsigned long *)&tbuf->tms_cstime);}return jiffies;
}

sys_brk

int sys_brk(unsigned long end_data_seg) //brk 数据段结尾
{if (end_data_seg >= current->end_code &&//如果end_data_seg大于当前进程的代码段结尾并且小于当前进程的(堆栈-16K),于是//把end_date_seg作为新的数据段结尾end_data_seg < current->start_stack - 16384)current->brk = end_data_seg;return current->brk;
}


sys_setpgid

/** This needs some heave checking ...* I just haven't get the stomach for it. I also don't fully* understand sessions/pgrp etc. Let somebody who does explain it.** OK, I think I have the protection semantics right.... this is really* only important on a multi-user system anyway, to make sure one user* can't send a signal to a process owned by another.  -TYT, 12/12/91*/
int sys_setpgid(int pid, int pgid)  
{int i;if (!pid)pid = current->pid;if (!pgid)pgid = current->pid;if (pgid < 0)return -EINVAL;for (i=0 ; i<NR_TASKS ; i++)if (task[i] && (task[i]->pid == pid) &&((task[i]->p_pptr == current) ||(task[i] == current))) {if (task[i]->leader)return -EPERM;if ((task[i]->session != current->session) ||((pgid != pid) &&(session_of_pgrp(pgid) != current->session)))return -EPERM;task[i]->pgrp = pgid;return 0;}return -ESRCH;
}


 getpgrp

int sys_getpgrp(void) //获得当前进程的pgrp == process group
{return current->pgrp;
}

setsid

int sys_setsid(void) //设置session ID
{if (current->leader && !suser()) //当前进程不是session leader或者拥有超级权限的话是无法更改session ID的return -EPERM;current->leader = 1; //当前进程被确认为session leadercurrent->session = current->pgrp = current->pid;current->tty = -1;return current->pgrp;
}


getgroups

/** Supplementary group ID's*/
int sys_getgroups(int gidsetsize, gid_t *grouplist)
//这里应该有问题,一个进程不可能属于多一个进程组
//原因很简单,一个进程的group id只能是一个值!这就约束了它就只能属于一个进程组!他的group leader只能有一个!
{int    i;if (gidsetsize)verify_area(grouplist, sizeof(gid_t) * gidsetsize);for (i = 0; (i < NGROUPS) && (current->groups[i] != NOGROUP);i++, grouplist++) {if (gidsetsize) {if (i >= gidsetsize)return -EINVAL;put_fs_word(current->groups[i], (short *) grouplist);}}return(i);
}

uname

static struct utsname thisname = {UTS_SYSNAME, UTS_NODENAME, UTS_RELEASE, UTS_VERSION, UTS_MACHINE
};int sys_uname(struct utsname * name) //获取系统名称信息
{int i;if (!name) return -ERROR;verify_area(name,sizeof *name);for(i=0;i<sizeof *name;i++)put_fs_byte(((char *) &thisname)[i],i+(char *) name);return 0;
}

sethostname

/** Only sethostname; gethostname can be implemented by calling uname()*/
int sys_sethostname(char *name, int len) //设置系统名词信息
{int    i;if (!suser())return -EPERM;if (len > MAXHOSTNAMELEN)return -EINVAL;for (i=0; i < len; i++) {if ((thisname.nodename[i] = get_fs_byte(name+i)) == 0)break;}if (thisname.nodename[i]) {thisname.nodename[i>MAXHOSTNAMELEN ? MAXHOSTNAMELEN : i] = 0;}return 0;
}

getrlimit


int sys_getrlimit(int resource, struct rlimit *rlim) //获取当前进程的资源界限值
{if (resource >= RLIM_NLIMITS)return -EINVAL;verify_area(rlim,sizeof *rlim);put_fs_long(current->rlim[resource].rlim_cur,(unsigned long *) rlim);put_fs_long(current->rlim[resource].rlim_max,((unsigned long *) rlim)+1);return 0;    
}

setrlimit


int sys_setrlimit(int resource, struct rlimit *rlim)
{struct rlimit new, *old;if (resource >= RLIM_NLIMITS)return -EINVAL;old = current->rlim + resource;new.rlim_cur = get_fs_long((unsigned long *) rlim);new.rlim_max = get_fs_long(((unsigned long *) rlim)+1);if (((new.rlim_cur > old->rlim_max) ||(new.rlim_max > old->rlim_max)) &&!suser())return -EPERM;*old = new;return 0;
}

umask

int sys_umask(int mask)//当设置当前进程创建文件的属性
{int old = current->umask;current->umask = mask & 0777;return (old);
}












 



这篇关于《linux 内核完全剖析》 sys.c 代码分析的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1035806

相关文章

Oracle数据库定时备份脚本方式(Linux)

《Oracle数据库定时备份脚本方式(Linux)》文章介绍Oracle数据库自动备份方案,包含主机备份传输与备机解压导入流程,强调需提前全量删除原库数据避免报错,并需配置无密传输、定时任务及验证脚本... 目录说明主机脚本备机上自动导库脚本整个自动备份oracle数据库的过程(建议全程用root用户)总结

MySQL 内存使用率常用分析语句

《MySQL内存使用率常用分析语句》用户整理了MySQL内存占用过高的分析方法,涵盖操作系统层确认及数据库层bufferpool、内存模块差值、线程状态、performance_schema性能数据... 目录一、 OS层二、 DB层1. 全局情况2. 内存占js用详情最近连续遇到mysql内存占用过高导致

Linux如何查看文件权限的命令

《Linux如何查看文件权限的命令》Linux中使用ls-R命令递归查看指定目录及子目录下所有文件和文件夹的权限信息,以列表形式展示权限位、所有者、组等详细内容... 目录linux China编程查看文件权限命令输出结果示例这里是查看tomcat文件夹总结Linux 查看文件权限命令ls -l 文件或文件夹

idea的终端(Terminal)cmd的命令换成linux的命令详解

《idea的终端(Terminal)cmd的命令换成linux的命令详解》本文介绍IDEA配置Git的步骤:安装Git、修改终端设置并重启IDEA,强调顺序,作为个人经验分享,希望提供参考并支持脚本之... 目录一编程、设置前二、前置条件三、android设置四、设置后总结一、php设置前二、前置条件

深度解析Nginx日志分析与499状态码问题解决

《深度解析Nginx日志分析与499状态码问题解决》在Web服务器运维和性能优化过程中,Nginx日志是排查问题的重要依据,本文将围绕Nginx日志分析、499状态码的成因、排查方法及解决方案展开讨论... 目录前言1. Nginx日志基础1.1 Nginx日志存放位置1.2 Nginx日志格式2. 499

Linux系统中查询JDK安装目录的几种常用方法

《Linux系统中查询JDK安装目录的几种常用方法》:本文主要介绍Linux系统中查询JDK安装目录的几种常用方法,方法分别是通过update-alternatives、Java命令、环境变量及目... 目录方法 1:通过update-alternatives查询(推荐)方法 2:检查所有已安装的 JDK方

Linux系统之lvcreate命令使用解读

《Linux系统之lvcreate命令使用解读》lvcreate是LVM中创建逻辑卷的核心命令,支持线性、条带化、RAID、镜像、快照、瘦池和缓存池等多种类型,实现灵活存储资源管理,需注意空间分配、R... 目录lvcreate命令详解一、命令概述二、语法格式三、核心功能四、选项详解五、使用示例1. 创建逻

Linux下在线安装启动VNC教程

《Linux下在线安装启动VNC教程》本文指导在CentOS7上在线安装VNC,包含安装、配置密码、启动/停止、清理重启步骤及注意事项,强调需安装VNC桌面以避免黑屏,并解决端口冲突和目录权限问题... 目录描述安装VNC安装 VNC 桌面可能遇到的问题总结描js述linux中的VNC就类似于Window

linux下shell脚本启动jar包实现过程

《linux下shell脚本启动jar包实现过程》确保APP_NAME和LOG_FILE位于目录内,首次启动前需手动创建log文件夹,否则报错,此为个人经验,供参考,欢迎支持脚本之家... 目录linux下shell脚本启动jar包样例1样例2总结linux下shell脚本启动jar包样例1#!/bin

Linux之platform平台设备驱动详解

《Linux之platform平台设备驱动详解》Linux设备驱动模型中,Platform总线作为虚拟总线统一管理无物理总线依赖的嵌入式设备,通过platform_driver和platform_de... 目录platform驱动注册platform设备注册设备树Platform驱动和设备的关系总结在 l