《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-基础知识3

打包和压缩 zip 安装zip软件包 yum -y install zip unzip 压缩打包命令: zip -q -r -d -u 压缩包文件名 目录和文件名列表 -q:不显示命令执行过程-r:递归处理,打包各级子目录和文件-u:把文件增加/替换到压缩包中-d:从压缩包中删除指定的文件 解压:unzip 压缩包名 打包文件 把压缩包从服务器下载到本地 把压缩包上传到服务器(zip

性能分析之MySQL索引实战案例

文章目录 一、前言二、准备三、MySQL索引优化四、MySQL 索引知识回顾五、总结 一、前言 在上一讲性能工具之 JProfiler 简单登录案例分析实战中已经发现SQL没有建立索引问题,本文将一起从代码层去分析为什么没有建立索引? 开源ERP项目地址:https://gitee.com/jishenghua/JSH_ERP 二、准备 打开IDEA找到登录请求资源路径位置

活用c4d官方开发文档查询代码

当你问AI助手比如豆包,如何用python禁止掉xpresso标签时候,它会提示到 这时候要用到两个东西。https://developers.maxon.net/论坛搜索和开发文档 比如这里我就在官方找到正确的id描述 然后我就把参数标签换过来

Linux 网络编程 --- 应用层

一、自定义协议和序列化反序列化 代码: 序列化反序列化实现网络版本计算器 二、HTTP协议 1、谈两个简单的预备知识 https://www.baidu.com/ --- 域名 --- 域名解析 --- IP地址 http的端口号为80端口,https的端口号为443 url为统一资源定位符。CSDNhttps://mp.csdn.net/mp_blog/creation/editor

【Python编程】Linux创建虚拟环境并配置与notebook相连接

1.创建 使用 venv 创建虚拟环境。例如,在当前目录下创建一个名为 myenv 的虚拟环境: python3 -m venv myenv 2.激活 激活虚拟环境使其成为当前终端会话的活动环境。运行: source myenv/bin/activate 3.与notebook连接 在虚拟环境中,使用 pip 安装 Jupyter 和 ipykernel: pip instal

内核启动时减少log的方式

内核引导选项 内核引导选项大体上可以分为两类:一类与设备无关、另一类与设备有关。与设备有关的引导选项多如牛毛,需要你自己阅读内核中的相应驱动程序源码以获取其能够接受的引导选项。比如,如果你想知道可以向 AHA1542 SCSI 驱动程序传递哪些引导选项,那么就查看 drivers/scsi/aha1542.c 文件,一般在前面 100 行注释里就可以找到所接受的引导选项说明。大多数选项是通过"_

poj 1258 Agri-Net(最小生成树模板代码)

感觉用这题来当模板更适合。 题意就是给你邻接矩阵求最小生成树啦。~ prim代码:效率很高。172k...0ms。 #include<stdio.h>#include<algorithm>using namespace std;const int MaxN = 101;const int INF = 0x3f3f3f3f;int g[MaxN][MaxN];int n

Linux_kernel驱动开发11

一、改回nfs方式挂载根文件系统         在产品将要上线之前,需要制作不同类型格式的根文件系统         在产品研发阶段,我们还是需要使用nfs的方式挂载根文件系统         优点:可以直接在上位机中修改文件系统内容,延长EMMC的寿命         【1】重启上位机nfs服务         sudo service nfs-kernel-server resta

计算机毕业设计 大学志愿填报系统 Java+SpringBoot+Vue 前后端分离 文档报告 代码讲解 安装调试

🍊作者:计算机编程-吉哥 🍊简介:专业从事JavaWeb程序开发,微信小程序开发,定制化项目、 源码、代码讲解、文档撰写、ppt制作。做自己喜欢的事,生活就是快乐的。 🍊心愿:点赞 👍 收藏 ⭐评论 📝 🍅 文末获取源码联系 👇🏻 精彩专栏推荐订阅 👇🏻 不然下次找不到哟~Java毕业设计项目~热门选题推荐《1000套》 目录 1.技术选型 2.开发工具 3.功能