Users and permissions: accounts, login, enforced file permissions, setuid, su, passwd, doas
The kernel now checks owner/group/other on open, create, unlink, rename, exec and path search; honours set-user-id and set-group-id; restricts kill, mount, reboot and mknod; keeps supplementary groups; and implements chown. devtmpfs nodes carry owners and modes that chmod/chown keep. Terminals run login, the image has root and schos, X starts as the ordinary user. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01EVRhxi9zpdW2uDUN4FVcao
This commit is contained in:
parent
b3f72cd95e
commit
020aa6113c
34 changed files with 1342 additions and 120 deletions
|
|
@ -532,6 +532,7 @@ found:
|
|||
p->sid = 0;
|
||||
p->uid = p->euid = p->suid = 0;
|
||||
p->gid = p->egid = p->sgid = 0;
|
||||
p->ngroups = 0;
|
||||
|
||||
release(&ptable.lock);
|
||||
|
||||
|
|
@ -760,6 +761,8 @@ fork(void)
|
|||
np->ctty = myproc()->ctty;
|
||||
np->uid = myproc()->uid; np->euid = myproc()->euid; np->suid = myproc()->suid;
|
||||
np->gid = myproc()->gid; np->egid = myproc()->egid; np->sgid = myproc()->sgid;
|
||||
np->ngroups = myproc()->ngroups;
|
||||
memmove(np->groups, myproc()->groups, sizeof(np->groups));
|
||||
|
||||
np->cwd = idup(myproc()->cwd);
|
||||
np->root = myproc()->root ? idup(myproc()->root) : 0;
|
||||
|
|
@ -1167,6 +1170,8 @@ clone_proc(uint64 flags, uint64 stack, uint64 ptid, uint64 ctid, uint64 tls)
|
|||
np->ctty = cur->ctty;
|
||||
np->uid = cur->uid; np->euid = cur->euid; np->suid = cur->suid;
|
||||
np->gid = cur->gid; np->egid = cur->egid; np->sgid = cur->sgid;
|
||||
np->ngroups = cur->ngroups;
|
||||
memmove(np->groups, cur->groups, sizeof(np->groups));
|
||||
np->cwd = idup(cur->cwd);
|
||||
np->root = cur->root ? idup(cur->root) : 0;
|
||||
memmove(np->cwd_path, cur->cwd_path, sizeof(cur->cwd_path));
|
||||
|
|
@ -2614,8 +2619,21 @@ sig_to_threads(struct proc *p, int sig)
|
|||
}
|
||||
}
|
||||
|
||||
int
|
||||
sigsend(int pid, int sig)
|
||||
// May `from` signal `to`? Root may; anyone else only a process whose real or
|
||||
// saved user id is one of their own ids -- kill(2)'s rule.
|
||||
static int
|
||||
sig_permitted(struct proc *from, struct proc *to)
|
||||
{
|
||||
if(from == 0 || from->euid == 0)
|
||||
return 1;
|
||||
return from->uid == to->uid || from->uid == to->suid ||
|
||||
from->euid == to->uid || from->euid == to->suid;
|
||||
}
|
||||
|
||||
// `check` is for a signal a process sends on purpose, by kill(2). The kernel's
|
||||
// own -- SIGPIPE, the terminal's SIGINT -- is nobody's to refuse.
|
||||
static int
|
||||
sigsend_x(int pid, int sig, int check)
|
||||
{
|
||||
struct proc *p;
|
||||
|
||||
|
|
@ -2625,6 +2643,10 @@ sigsend(int pid, int sig)
|
|||
acquire(&ptable.lock);
|
||||
for(p = ptable.proc; p < &ptable.proc[NPROC]; p++){
|
||||
if(p->pid == pid && p->state != UNUSED && p->state != ZOMBIE){
|
||||
if(check && !sig_permitted(myproc(), p)){
|
||||
release(&ptable.lock);
|
||||
return -2;
|
||||
}
|
||||
if(init_ignores(p, sig)){
|
||||
release(&ptable.lock);
|
||||
return 0; // silently dropped, as POSIX requires
|
||||
|
|
@ -2652,16 +2674,29 @@ sigsend(int pid, int sig)
|
|||
return -1;
|
||||
}
|
||||
|
||||
int
|
||||
sigsend(int pid, int sig)
|
||||
{
|
||||
return sigsend_x(pid, sig, 0);
|
||||
}
|
||||
|
||||
// -1 if there is no such process, -2 if there is and the caller may not.
|
||||
int
|
||||
sigsend_user(int pid, int sig)
|
||||
{
|
||||
return sigsend_x(pid, sig, 1);
|
||||
}
|
||||
|
||||
// Deliver a signal to every member of a process group. This is what job
|
||||
// control actually needs: a shell sends SIGINT/SIGTSTP/SIGHUP to a *group*,
|
||||
// never to individual pids. sys_kill() with pid <= 0 routes here.
|
||||
//
|
||||
// Returns 0 if at least one process was signalled, -1 if the group is empty.
|
||||
int
|
||||
sigsend_pgrp(int pgid, int sig)
|
||||
static int
|
||||
sigsend_pgrp_x(int pgid, int sig, int check)
|
||||
{
|
||||
struct proc *p;
|
||||
int found = 0;
|
||||
int found = 0, denied = 0;
|
||||
|
||||
if(sig < 0 || sig >= 32)
|
||||
return -1;
|
||||
|
|
@ -2672,6 +2707,10 @@ sigsend_pgrp(int pgid, int sig)
|
|||
continue;
|
||||
if(p->pgid != pgid)
|
||||
continue;
|
||||
if(check && !sig_permitted(myproc(), p)){
|
||||
denied = 1;
|
||||
continue;
|
||||
}
|
||||
found = 1;
|
||||
if(sig == 0)
|
||||
continue; // signal 0 is an existence probe only
|
||||
|
|
@ -2701,7 +2740,19 @@ sigsend_pgrp(int pgid, int sig)
|
|||
}
|
||||
release(&ptable.lock);
|
||||
|
||||
return found ? 0 : -1;
|
||||
return found ? 0 : denied ? -2 : -1;
|
||||
}
|
||||
|
||||
int
|
||||
sigsend_pgrp(int pgid, int sig)
|
||||
{
|
||||
return sigsend_pgrp_x(pgid, sig, 0);
|
||||
}
|
||||
|
||||
int
|
||||
sigsend_pgrp_user(int pgid, int sig)
|
||||
{
|
||||
return sigsend_pgrp_x(pgid, sig, 1);
|
||||
}
|
||||
|
||||
// Look up a process's process-group id. Returns -1 if no such live process.
|
||||
|
|
|
|||
Loading…
Reference in a new issue