Added setXid/getXid, chdir

This commit is contained in:
Mark
2020-01-13 17:30:09 +02:00
parent 7100c0ff07
commit f00a4a2eac
15 changed files with 197 additions and 67 deletions
+4
View File
@@ -5,6 +5,10 @@ void sys_exit(int status);
int sys_kill(int pid, int signum);
int sys_waitpid(int pid, int *status);
int sys_getpid(void);
int sys_setuid(uid_t uid);
int sys_setgid(gid_t gid);
uid_t sys_getuid(void);
gid_t sys_getgid(void);
// Non-compliant with linux style, but fuck'em, it just works
void sys_signal(uintptr_t entry);
+1 -1
View File
@@ -5,4 +5,4 @@
int sys_gettimeofday(struct timeval *tv, struct timezone *tz);
int sys_nanosleep(const struct timespec *req, struct timespec *rem);
int sys_reboot(int magic1, int magic2, unsigned int cmd, void *arg);
int sys_mount(const char *dev_name, const char *dir_name, const char *type, unsigned long flags, void *data);
+1
View File
@@ -67,6 +67,7 @@ struct vnode {
gid_t gid;
uid_t uid;
mode_t mode;
struct fs *fs;
void *fs_data;
+5
View File
@@ -23,7 +23,12 @@
#define SYSCALL_NR_EXIT 60
#define SYSCALL_NR_KILL 62
#define SYSCALL_NR_GETTIMEOFDAY 96
#define SYSCALL_NR_GETUID 102
#define SYSCALL_NR_GETGID 104
#define SYSCALL_NR_SETUID 105
#define SYSCALL_NR_SETGID 106
#define SYSCALL_NR_MOUNT 165
#define SYSCALL_NR_REBOOT 169
#define SYSCALL_NRX_OPENPTY 118
+36
View File
@@ -104,3 +104,39 @@ int sys_getpid(void) {
_assert(thr);
return thr->pid;
}
int sys_setuid(uid_t uid) {
struct thread *thr = get_cpu()->thread;
_assert(thr);
if (thr->ioctx.uid != 0) {
return -EACCES;
}
thr->ioctx.uid = uid;
return 0;
}
int sys_setgid(gid_t gid) {
struct thread *thr = get_cpu()->thread;
_assert(thr);
if (thr->ioctx.gid != 0) {
return -EACCES;
}
thr->ioctx.gid = gid;
return 0;
}
uid_t sys_getuid(void) {
struct thread *thr = get_cpu()->thread;
_assert(thr);
return thr->ioctx.uid;
}
gid_t sys_getgid(void) {
struct thread *thr = get_cpu()->thread;
_assert(thr);
return thr->ioctx.gid;
}
+31
View File
@@ -6,6 +6,37 @@
#include "sys/errno.h"
#include "sys/sched.h"
int sys_mount(const char *dev_name, const char *dir_name, const char *type, unsigned long flags, void *data) {
struct thread *thr = get_cpu()->thread;
struct vnode *dev_node;
void *dev;
int res;
_assert(thr);
_assert(dir_name);
if (thr->ioctx.uid != 0) {
// Only root can do that
return -EACCES;
}
if (dev_name) {
if ((res = vfs_find(&thr->ioctx, thr->ioctx.cwd_vnode, dev_name, &dev_node)) != 0) {
return res;
}
// Check that it's a block device:
if (dev_node->type != VN_BLK) {
return -EINVAL;
}
dev = dev_node->dev;
} else {
dev = NULL;
}
return vfs_mount(&thr->ioctx, dir_name, dev, type, NULL);
}
int sys_nanosleep(const struct timespec *req, struct timespec *rem) {
struct thread *cur_thread = get_cpu()->thread;
_assert(cur_thread);
+5
View File
@@ -35,8 +35,13 @@ const void *amd64_syscall_jmp_table[256] = {
[SYSCALL_NRX_SIGRET] = sys_sigret,
[SYSCALL_NRX_SIGNAL] = sys_signal,
[SYSCALL_NRX_WAITPID] = sys_waitpid,
[SYSCALL_NR_SETUID] = sys_setuid,
[SYSCALL_NR_SETGID] = sys_setgid,
[SYSCALL_NR_GETUID] = sys_getuid,
[SYSCALL_NR_GETGID] = sys_getgid,
// System
[SYSCALL_NR_MOUNT] = sys_mount,
[SYSCALL_NR_REBOOT] = sys_reboot,
[SYSCALL_NR_NANOSLEEP] = sys_nanosleep,
[SYSCALL_NR_GETTIMEOFDAY] = sys_gettimeofday,
+12
View File
@@ -46,6 +46,9 @@ static void devfs_ensure_root(void) {
if (!devfs_root) {
devfs_root = vnode_create(VN_DIR, NULL);
devfs_root->flags |= VN_MEMORY;
devfs_root->mode = 0555;
devfs_root->uid = 0;
devfs_root->gid = 0;
}
}
@@ -68,6 +71,10 @@ int dev_add_link(const char *name, struct vnode *to) {
devfs_ensure_root();
node->mode = 0777;
node->uid = 0;
node->gid = 0;
vnode_attach(devfs_root, node);
return 0;
@@ -94,6 +101,11 @@ int dev_add(enum dev_class cls, int subcls, void *dev, const char *name) {
node->flags |= VN_MEMORY;
// Default permissions for devices
node->mode = 0600;
node->uid = 0;
node->gid = 0;
devfs_ensure_root();
// TODO: some devices are located in subdirs
+4
View File
@@ -113,6 +113,10 @@ static struct vnode *ext2_fs_get_root(struct fs *fs) {
res->op = &ext2_vnode_ops;
res->type = ext2_inode_type(inode);
res->uid = inode->uid;
res->gid = inode->gid;
res->mode = inode->type_perm;
return res;
}
+27 -27
View File
@@ -29,7 +29,7 @@ static ssize_t ext2_vnode_write(struct ofile *fd, const void *buf, size_t count)
static int ext2_vnode_truncate(struct vnode *vn, size_t length);
static ssize_t ext2_vnode_readdir(struct ofile *fd, struct dirent *ent);
//static void ext2_vnode_destroy(vnode_t *vn);
//static int ext2_vnode_stat(vnode_t *vn, struct stat *st);
static int ext2_vnode_stat(struct vnode *vn, struct stat *st);
//static int ext2_vnode_chmod(vnode_t *vn, mode_t mode);
//static int ext2_vnode_chown(vnode_t *vn, uid_t uid, gid_t gid);
//static int ext2_vnode_unlink(vnode_t *at, vnode_t *vn, const char *name);
@@ -48,7 +48,7 @@ struct vnode_operations ext2_vnode_ops = {
//
// .chmod = ext2_vnode_chmod,
// .chown = ext2_vnode_chown,
// .stat = ext2_vnode_stat,
.stat = ext2_vnode_stat,
// .unlink = ext2_vnode_unlink,
// .access = ext2_vnode_access,
//
@@ -550,31 +550,31 @@ static ssize_t ext2_vnode_readdir(struct ofile *fd, struct dirent *vfsdir) {
// // Release inode struct
// kfree(vn->fs_data);
//}
//
//static int ext2_vnode_stat(vnode_t *vn, struct stat *st) {
// _assert(vn && vn->fs);
// struct ext2_inode *inode = (struct ext2_inode *) vn->fs_data;
// _assert(inode);
// struct ext2_extsb *sb = (struct ext2_extsb *) vn->fs->fs_private;
// _assert(sb);
//
// st->st_atime = inode->atime;
// st->st_ctime = inode->ctime;
// st->st_mtime = inode->mtime;
// st->st_dev = 0; // Not implemented
// st->st_rdev = 0; // Not implemented
// st->st_gid = inode->gid;
// st->st_uid = inode->uid;
// st->st_mode = inode->type_perm;
// st->st_size = inode->size_lower;
// st->st_blocks = (inode->size_lower + sb->block_size - 1) / sb->block_size;
// st->st_blksize = sb->block_size;
// st->st_nlink = 0;
// st->st_ino = vn->fs_number;
//
// return 0;
//}
//
static int ext2_vnode_stat(struct vnode *vn, struct stat *st) {
_assert(vn && vn->fs);
struct ext2_inode *inode = (struct ext2_inode *) vn->fs_data;
_assert(inode);
struct ext2_extsb *sb = (struct ext2_extsb *) vn->fs->fs_private;
_assert(sb);
st->st_atime = inode->atime;
st->st_ctime = inode->ctime;
st->st_mtime = inode->mtime;
st->st_dev = 0; // Not implemented
st->st_rdev = 0; // Not implemented
st->st_gid = inode->gid;
st->st_uid = inode->uid;
st->st_mode = inode->type_perm;
st->st_size = inode->size_lower;
st->st_blocks = (inode->size_lower + sb->block_size - 1) / sb->block_size;
st->st_blksize = sb->block_size;
st->st_nlink = 0;
st->st_ino = vn->ino;
return 0;
}
//static int ext2_vnode_chmod(vnode_t *vn, mode_t mode) {
// _assert(vn && vn->fs && vn->fs_data);
// struct ext2_inode *inode = (struct ext2_inode *) vn->fs_data;
+4
View File
@@ -28,6 +28,10 @@ struct vnode *vnode_create(enum vnode_type t, const char *name) {
node->op = NULL;
node->dev = NULL;
node->uid = 0;
node->gid = 0;
node->mode = 0644;
if (name) {
_assert(strlen(name) < NODE_MAXLEN);
strcpy(node->name, name);
+7 -2
View File
@@ -127,6 +127,10 @@ static int tar_init(struct fs *tar, const char *opt) {
tar_root->fs = tar;
tar_root->flags |= VN_MEMORY;
tar_root->uid = 0;
tar_root->gid = 0;
tar_root->mode = 0555;
struct vnode *node;
while (1) {
@@ -160,8 +164,9 @@ static int tar_init(struct fs *tar, const char *opt) {
_assert(node);
// Initialize the vnode
node->uid = 0;
node->gid = 0;
node->uid = tarfs_octal(hdr->uid, 8);
node->gid = tarfs_octal(hdr->gid, 8);
node->mode = tarfs_octal(hdr->mode, 8);
struct tarfs_vnode_attr *attr = kmalloc(sizeof(struct tarfs_vnode_attr));
_assert(attr);
+47 -31
View File
@@ -2,6 +2,7 @@
#include "sys/fs/fs.h"
#include "sys/string.h"
#include "sys/assert.h"
#include "sys/fcntl.h"
#include "sys/panic.h"
#include "sys/debug.h"
#include "sys/errno.h"
@@ -15,9 +16,15 @@ struct vfs_ioctx *const kernel_ioctx = &_kernel_ioctx;
int vfs_setcwd(struct vfs_ioctx *ctx, const char *path) {
struct vnode *node;
struct vnode *dst;
int res;
if (path[0] == '/') {
if (path[1] == 0) {
ctx->cwd_vnode = NULL;
return 0;
}
if (!vfs_root) {
ctx->cwd_vnode = NULL;
} else {
@@ -25,8 +32,24 @@ int vfs_setcwd(struct vfs_ioctx *ctx, const char *path) {
return res;
}
// TODO: access, check if directory
ctx->cwd_vnode = node;
// Resolve mounts and symlinks
if ((res = vfs_link_resolve(ctx, node, &dst)) != 0) {
return res;
}
if (dst->type == VN_MNT) {
_assert(dst->target);
dst = dst->target;
}
if (dst->type != VN_DIR) {
return -ENOTDIR;
}
if ((res = vfs_access_node(ctx, dst, X_OK)) != 0) {
return res;
}
ctx->cwd_vnode = dst;
}
return 0;
} else {
@@ -34,8 +57,23 @@ int vfs_setcwd(struct vfs_ioctx *ctx, const char *path) {
return res;
}
// TODO: access, check if directory
ctx->cwd_vnode = node;
if ((res = vfs_link_resolve(ctx, node, &dst)) != 0) {
return res;
}
if (dst->type == VN_MNT) {
_assert(dst->target);
dst = dst->target;
}
if (dst->type != VN_DIR) {
return -ENOTDIR;
}
if ((res = vfs_access_node(ctx, dst, X_OK)) != 0) {
return res;
}
ctx->cwd_vnode = dst;
return 0;
}
@@ -56,31 +94,8 @@ void vfs_vnode_path(char *path, struct vnode *node) {
return;
}
size_t bstp = 10;
while (node) {
if (bstp == 0) {
panic("Node stack overflow\n");
}
backstack[--bstp] = node;
node = node->parent;
}
for (size_t i = bstp; i < 10; ++i) {
size_t len;
if (backstack[i]->parent) {
// Non-root
len = strlen(backstack[i]->name);
strcpy(path + c, backstack[i]->name);
} else {
len = 0;
}
c += len;
if (i != 9) {
path[c] = '/';
}
++c;
}
path[0] = '?';
path[1] = 0;
}
static const char *path_element(const char *path, char *element) {
@@ -234,13 +249,14 @@ static int vfs_find_internal(struct vfs_ioctx *ctx, struct vnode *at, const char
++path;
}
child_path = path;
while (1) {
child_path = path_element(path, name);
child_path = path_element(child_path, name);
if (!strcmp(name, ".")) {
// Refers to this node
kdebug(". hit %s\n", at->name);
if (!child_path) {
if (!child_path || !*child_path) {
*child = at;
return 0;
}
+8 -5
View File
@@ -60,11 +60,14 @@ int vfs_access_node(struct vfs_ioctx *ctx, struct vnode *vn, int mode) {
_assert(vn);
if (!vn->op || !vn->op->access) {
return 0;
}
if ((res = vn->op->access(vn, &vn_uid, &vn_gid, &vn_mode)) != 0) {
return res;
vn_mode = vn->mode;
vn_uid = vn->uid;
vn_gid = vn->gid;
} else {
// Filesystem has non-trivial permission storage
if ((res = vn->op->access(vn, &vn_uid, &vn_gid, &vn_mode)) != 0) {
return res;
}
}
return vfs_access_check(ctx, mode, vn_mode, vn_uid, vn_gid);
+5 -1
View File
@@ -256,6 +256,11 @@ int vfs_creat(struct vfs_ioctx *ctx, const char *path, mode_t mode) {
return res;
}
// Check permission for writing
if ((res = vfs_access_node(ctx, at, W_OK)) != 0) {
return res;
}
// TODO: check if such file already exists
if (!at->op || !at->op->creat) {
// Assume it's a read-only filesystem
@@ -338,7 +343,6 @@ int vfs_stat(struct vfs_ioctx *ctx, const char *path, struct stat *st) {
}
if (!node->op || !node->op->stat) {
kwarn("%s: filesystem has no stat()\n", path);
return -EINVAL;
}