mirror of
https://github.com/RGBCube/serenity
synced 2025-07-24 17:27:35 +00:00
Kernel+Userland: Implement setuid() and setgid() and add /bin/su
Also show setuid and setgid bits in "ls -l" output. :^)
This commit is contained in:
parent
6071a77e8e
commit
920e8e58ed
9 changed files with 79 additions and 8 deletions
|
@ -1,2 +1,3 @@
|
||||||
root:x:0:0:root:/:/bin/sh
|
root:x:0:0:root:/:/bin/sh
|
||||||
anon:x:100:100:Anonymous,,,:/home/anon:/bin/sh
|
anon:x:100:100:Anonymous,,,:/home/anon:/bin/sh
|
||||||
|
nona:x:200:200:Nona,,,:/home/nona:/bin/sh
|
||||||
|
|
|
@ -411,6 +411,11 @@ int Process::do_exec(String path, Vector<String> arguments, Vector<String> envir
|
||||||
m_initial_arguments = move(arguments);
|
m_initial_arguments = move(arguments);
|
||||||
m_initial_environment = move(environment);
|
m_initial_environment = move(environment);
|
||||||
|
|
||||||
|
if (descriptor->metadata().is_setuid())
|
||||||
|
m_euid = descriptor->metadata().uid;
|
||||||
|
if (descriptor->metadata().is_setgid())
|
||||||
|
m_egid = descriptor->metadata().gid;
|
||||||
|
|
||||||
#ifdef TASK_DEBUG
|
#ifdef TASK_DEBUG
|
||||||
kprintf("Process %u (%s) exec'd %s @ %p\n", pid(), name().characters(), path.characters(), m_tss.eip);
|
kprintf("Process %u (%s) exec'd %s @ %p\n", pid(), name().characters(), path.characters(), m_tss.eip);
|
||||||
#endif
|
#endif
|
||||||
|
@ -1352,14 +1357,22 @@ int Process::sys$killpg(int pgrp, int signum)
|
||||||
ASSERT_NOT_REACHED();
|
ASSERT_NOT_REACHED();
|
||||||
}
|
}
|
||||||
|
|
||||||
int Process::sys$setuid(uid_t)
|
int Process::sys$setuid(uid_t uid)
|
||||||
{
|
{
|
||||||
ASSERT_NOT_REACHED();
|
if (uid != m_uid && !is_superuser())
|
||||||
|
return -EPERM;
|
||||||
|
m_uid = uid;
|
||||||
|
m_euid = uid;
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int Process::sys$setgid(gid_t)
|
int Process::sys$setgid(gid_t gid)
|
||||||
{
|
{
|
||||||
ASSERT_NOT_REACHED();
|
if (gid != m_gid && !is_superuser())
|
||||||
|
return -EPERM;
|
||||||
|
m_gid = gid;
|
||||||
|
m_egid = gid;
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned Process::sys$alarm(unsigned seconds)
|
unsigned Process::sys$alarm(unsigned seconds)
|
||||||
|
@ -1900,7 +1913,7 @@ int Process::sys$getgroups(int count, gid_t* gids)
|
||||||
|
|
||||||
int Process::sys$setgroups(size_t count, const gid_t* gids)
|
int Process::sys$setgroups(size_t count, const gid_t* gids)
|
||||||
{
|
{
|
||||||
if (!is_root())
|
if (!is_superuser())
|
||||||
return -EPERM;
|
return -EPERM;
|
||||||
if (count >= MAX_PROCESS_GIDS)
|
if (count >= MAX_PROCESS_GIDS)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
|
@ -283,7 +283,7 @@ public:
|
||||||
Process* fork(RegisterDump&);
|
Process* fork(RegisterDump&);
|
||||||
int exec(String path, Vector<String> arguments, Vector<String> environment);
|
int exec(String path, Vector<String> arguments, Vector<String> environment);
|
||||||
|
|
||||||
bool is_root() const { return m_euid == 0; }
|
bool is_superuser() const { return m_euid == 0; }
|
||||||
|
|
||||||
bool wakeup_requested() { return m_wakeup_requested; }
|
bool wakeup_requested() { return m_wakeup_requested; }
|
||||||
void request_wakeup() { m_wakeup_requested = true; }
|
void request_wakeup() { m_wakeup_requested = true; }
|
||||||
|
|
|
@ -32,7 +32,10 @@ ln -s /proc/self/fd/0 mnt/dev/stdin
|
||||||
ln -s /proc/self/fd/1 mnt/dev/stdout
|
ln -s /proc/self/fd/1 mnt/dev/stdout
|
||||||
ln -s /proc/self/fd/2 mnt/dev/stderr
|
ln -s /proc/self/fd/2 mnt/dev/stderr
|
||||||
cp -vR ../Base/* mnt/
|
cp -vR ../Base/* mnt/
|
||||||
|
mkdir mnt/home/anon
|
||||||
|
mkdir mnt/home/nona
|
||||||
chown -vR 100:100 mnt/home/anon
|
chown -vR 100:100 mnt/home/anon
|
||||||
|
chown -vR 200:200 mnt/home/nona
|
||||||
cp -v ../Userland/sh mnt/bin/sh
|
cp -v ../Userland/sh mnt/bin/sh
|
||||||
cp -v ../Userland/id mnt/bin/id
|
cp -v ../Userland/id mnt/bin/id
|
||||||
cp -v ../Userland/ps mnt/bin/ps
|
cp -v ../Userland/ps mnt/bin/ps
|
||||||
|
@ -65,6 +68,8 @@ cp -v ../Userland/chmod mnt/bin/chmod
|
||||||
cp -v ../Userland/top mnt/bin/top
|
cp -v ../Userland/top mnt/bin/top
|
||||||
cp -v ../Userland/ln mnt/bin/ln
|
cp -v ../Userland/ln mnt/bin/ln
|
||||||
cp -v ../Userland/df mnt/bin/df
|
cp -v ../Userland/df mnt/bin/df
|
||||||
|
cp -v ../Userland/su mnt/bin/su
|
||||||
|
chmod 4755 mnt/bin/su
|
||||||
cp -v ../Applications/Terminal/Terminal mnt/bin/Terminal
|
cp -v ../Applications/Terminal/Terminal mnt/bin/Terminal
|
||||||
cp -v ../Applications/FontEditor/FontEditor mnt/bin/FontEditor
|
cp -v ../Applications/FontEditor/FontEditor mnt/bin/FontEditor
|
||||||
cp -v ../Applications/Launcher/Launcher mnt/bin/Launcher
|
cp -v ../Applications/Launcher/Launcher mnt/bin/Launcher
|
||||||
|
|
|
@ -31,6 +31,8 @@ gid_t getgid();
|
||||||
pid_t getpid();
|
pid_t getpid();
|
||||||
int getgroups(int size, gid_t list[]);
|
int getgroups(int size, gid_t list[]);
|
||||||
int setgroups(size_t, const gid_t*);
|
int setgroups(size_t, const gid_t*);
|
||||||
|
int setuid(uid_t);
|
||||||
|
int setgid(gid_t);
|
||||||
pid_t tcgetpgrp(int fd);
|
pid_t tcgetpgrp(int fd);
|
||||||
int tcsetpgrp(int fd, pid_t pgid);
|
int tcsetpgrp(int fd, pid_t pgid);
|
||||||
int open(const char* path, int options, ...);
|
int open(const char* path, int options, ...);
|
||||||
|
|
1
Userland/.gitignore
vendored
1
Userland/.gitignore
vendored
|
@ -33,3 +33,4 @@ chmod
|
||||||
pape
|
pape
|
||||||
ln
|
ln
|
||||||
df
|
df
|
||||||
|
su
|
||||||
|
|
|
@ -29,6 +29,7 @@ OBJS = \
|
||||||
top.o \
|
top.o \
|
||||||
df.o \
|
df.o \
|
||||||
ln.o \
|
ln.o \
|
||||||
|
su.o \
|
||||||
rm.o
|
rm.o
|
||||||
|
|
||||||
APPS = \
|
APPS = \
|
||||||
|
@ -63,6 +64,7 @@ APPS = \
|
||||||
top \
|
top \
|
||||||
ln \
|
ln \
|
||||||
df \
|
df \
|
||||||
|
su \
|
||||||
rm
|
rm
|
||||||
|
|
||||||
ARCH_FLAGS =
|
ARCH_FLAGS =
|
||||||
|
@ -179,6 +181,9 @@ ln: ln.o
|
||||||
df: df.o
|
df: df.o
|
||||||
$(LD) -o $@ $(LDFLAGS) $< ../LibC/LibC.a
|
$(LD) -o $@ $(LDFLAGS) $< ../LibC/LibC.a
|
||||||
|
|
||||||
|
su: su.o
|
||||||
|
$(LD) -o $@ $(LDFLAGS) $< ../LibC/LibC.a
|
||||||
|
|
||||||
.cpp.o:
|
.cpp.o:
|
||||||
@echo "CXX $<"; $(CXX) $(CXXFLAGS) -o $@ -c $<
|
@echo "CXX $<"; $(CXX) $(CXXFLAGS) -o $@ -c $<
|
||||||
|
|
||||||
|
|
|
@ -148,10 +148,10 @@ int do_dir(const char* path)
|
||||||
printf("%c%c%c%c%c%c%c%c",
|
printf("%c%c%c%c%c%c%c%c",
|
||||||
st.st_mode & S_IRUSR ? 'r' : '-',
|
st.st_mode & S_IRUSR ? 'r' : '-',
|
||||||
st.st_mode & S_IWUSR ? 'w' : '-',
|
st.st_mode & S_IWUSR ? 'w' : '-',
|
||||||
st.st_mode & S_IXUSR ? 'x' : '-',
|
st.st_mode & S_ISUID ? 's' : (st.st_mode & S_IXUSR ? 'x' : '-'),
|
||||||
st.st_mode & S_IRGRP ? 'r' : '-',
|
st.st_mode & S_IRGRP ? 'r' : '-',
|
||||||
st.st_mode & S_IWGRP ? 'w' : '-',
|
st.st_mode & S_IWGRP ? 'w' : '-',
|
||||||
st.st_mode & S_IXGRP ? 'x' : '-',
|
st.st_mode & S_ISGID ? 's' : (st.st_mode & S_IXGRP ? 'x' : '-'),
|
||||||
st.st_mode & S_IROTH ? 'r' : '-',
|
st.st_mode & S_IROTH ? 'r' : '-',
|
||||||
st.st_mode & S_IWOTH ? 'w' : '-'
|
st.st_mode & S_IWOTH ? 'w' : '-'
|
||||||
);
|
);
|
||||||
|
|
44
Userland/su.cpp
Normal file
44
Userland/su.cpp
Normal file
|
@ -0,0 +1,44 @@
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <pwd.h>
|
||||||
|
#include <grp.h>
|
||||||
|
#include <alloca.h>
|
||||||
|
|
||||||
|
extern "C" int main(int, char**);
|
||||||
|
|
||||||
|
int main(int argc, char** argv)
|
||||||
|
{
|
||||||
|
uid_t uid;
|
||||||
|
gid_t gid;
|
||||||
|
if (argc == 1) {
|
||||||
|
uid = 0;
|
||||||
|
gid = 0;
|
||||||
|
} else {
|
||||||
|
auto* pwd = getpwnam(argv[1]);
|
||||||
|
if (!pwd) {
|
||||||
|
fprintf(stderr, "No such user: %s\n", argv[1]);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
uid = pwd->pw_uid;
|
||||||
|
gid = pwd->pw_gid;
|
||||||
|
}
|
||||||
|
|
||||||
|
int rc = setgid(uid);
|
||||||
|
if (rc < 0) {
|
||||||
|
perror("setgid");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
rc = setuid(gid);
|
||||||
|
if (rc < 0) {
|
||||||
|
perror("setuid");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
rc = execl("/bin/sh", "sh", nullptr);
|
||||||
|
if (rc < 0) {
|
||||||
|
perror("execl");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
Loading…
Add table
Add a link
Reference in a new issue