《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

相关文章

Linux脚本(shell)的使用方式

《Linux脚本(shell)的使用方式》:本文主要介绍Linux脚本(shell)的使用方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录概述语法详解数学运算表达式Shell变量变量分类环境变量Shell内部变量自定义变量:定义、赋值自定义变量:引用、修改、删

Python实例题之pygame开发打飞机游戏实例代码

《Python实例题之pygame开发打飞机游戏实例代码》对于python的学习者,能够写出一个飞机大战的程序代码,是不是感觉到非常的开心,:本文主要介绍Python实例题之pygame开发打飞机... 目录题目pygame-aircraft-game使用 Pygame 开发的打飞机游戏脚本代码解释初始化部

Java中Map.Entry()含义及方法使用代码

《Java中Map.Entry()含义及方法使用代码》:本文主要介绍Java中Map.Entry()含义及方法使用的相关资料,Map.Entry是Java中Map的静态内部接口,用于表示键值对,其... 目录前言 Map.Entry作用核心方法常见使用场景1. 遍历 Map 的所有键值对2. 直接修改 Ma

MyBatis Plus 中 update_time 字段自动填充失效的原因分析及解决方案(最新整理)

《MyBatisPlus中update_time字段自动填充失效的原因分析及解决方案(最新整理)》在使用MyBatisPlus时,通常我们会在数据库表中设置create_time和update... 目录前言一、问题现象二、原因分析三、总结:常见原因与解决方法对照表四、推荐写法前言在使用 MyBATis

Python主动抛出异常的各种用法和场景分析

《Python主动抛出异常的各种用法和场景分析》在Python中,我们不仅可以捕获和处理异常,还可以主动抛出异常,也就是以类的方式自定义错误的类型和提示信息,这在编程中非常有用,下面我将详细解释主动抛... 目录一、为什么要主动抛出异常?二、基本语法:raise关键字基本示例三、raise的多种用法1. 抛

Linux链表操作方式

《Linux链表操作方式》:本文主要介绍Linux链表操作方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录一、链表基础概念与内核链表优势二、内核链表结构与宏解析三、内核链表的优点四、用户态链表示例五、双向循环链表在内核中的实现优势六、典型应用场景七、调试技巧与

详解Linux中常见环境变量的特点与设置

《详解Linux中常见环境变量的特点与设置》环境变量是操作系统和用户设置的一些动态键值对,为运行的程序提供配置信息,理解环境变量对于系统管理、软件开发都很重要,下面小编就为大家详细介绍一下吧... 目录前言一、环境变量的概念二、常见的环境变量三、环境变量特点及其相关指令3.1 环境变量的全局性3.2、环境变

github打不开的问题分析及解决

《github打不开的问题分析及解决》:本文主要介绍github打不开的问题分析及解决,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录一、找到github.com域名解析的ip地址二、找到github.global.ssl.fastly.net网址解析的ip地址三

Linux系统中的firewall-offline-cmd详解(收藏版)

《Linux系统中的firewall-offline-cmd详解(收藏版)》firewall-offline-cmd是firewalld的一个命令行工具,专门设计用于在没有运行firewalld服务的... 目录主要用途基本语法选项1. 状态管理2. 区域管理3. 服务管理4. 端口管理5. ICMP 阻断

Linux实现线程同步的多种方式汇总

《Linux实现线程同步的多种方式汇总》本文详细介绍了Linux下线程同步的多种方法,包括互斥锁、自旋锁、信号量以及它们的使用示例,通过这些同步机制,可以解决线程安全问题,防止资源竞争导致的错误,示例... 目录什么是线程同步?一、互斥锁(单人洗手间规则)适用场景:特点:二、条件变量(咖啡厅取餐系统)工作流