本文主要是介绍《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 代码分析的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!