#define prefetch_rd(ptr, ll) __builtin_prefetch((ptr), 0, ll)
#define prefetch_wr(ptr, ll) __builtin_prefetch((ptr), 1, ll)
-#define stringify(v) #v
-#define stringify__(v) stringify(v)
+#define v__(v) (v)
+#define stringify(v) #v
+#define stringify__(v) stringify(v)
#define compact __attribute__((packed))
#define align(v) __attribute__((aligned (v)))
#include <lunaix/status.h>
#include <lunaix/spike.h>
#include <lunaix/bcache.h>
+#include <lunaix/fs_acl.h>
#include <usr/lunaix/fstypes.h>
u32_t link_count;
u32_t lb_usage;
u32_t fsize;
+
+ u32_t acl;
+ uid_t uid;
+ gid_t gid;
+
void* data; // 允许底层FS绑定他的一些专有数据
struct llist_header aka_dnodes;
struct llist_header xattrs;
return check_itype(inode->itype, VFS_IFSYMLINK);
}
+static inline bool
+check_allow_ops(struct v_inode* inode, unsigned int perm)
+{
+ return fsacl_allow_ops(perm, inode->acl, inode->uid, inode->gid);
+}
+
+static inline bool
+check_allow_read(struct v_inode* inode)
+{
+ return check_allow_ops(inode, FSACL_aR);
+}
+
+static inline bool
+check_allow_write(struct v_inode* inode)
+{
+ return check_allow_ops(inode, FSACL_aW);
+}
+
+static inline bool
+check_allow_execute(struct v_inode* inode)
+{
+ return check_allow_ops(inode, FSACL_aX);
+}
+
#endif /* __LUNAIX_VFS_H */
inode->atime = atime;
}
+static inline void
+fsapi_inode_setaccess(struct v_inode* inode, unsigned int acl)
+{
+ inode->acl = acl;
+}
+
+static inline void
+fsapi_inode_setowner(struct v_inode* inode, uid_t uid, gid_t gid)
+{
+ inode->uid = uid;
+ inode->gid = gid;
+}
+
static inline void
fsapi_dnode_setdector(struct v_dnode* dnode,
dnode_free free_cb)
--- /dev/null
+#ifndef __LUNAIX_FS_ACL_H
+#define __LUNAIX_FS_ACL_H
+
+#include <lunaix/usrscope.h>
+#include "compiler.h"
+
+#define FSACL_READ 4
+#define FSACL_WRITE 2
+#define FSACL_EXEC 1
+
+#define FSACL_U(x) (((x) & 0b111) << 6)
+#define FSACL_G(x) (((x) & 0b111) << 3)
+#define FSACL_O(x) ((x) & 0b111)
+
+#define FSACL_uR FSACL_U(FSACL_READ)
+#define FSACL_uW FSACL_U(FSACL_WRITE)
+#define FSACL_uX FSACL_U(FSACL_EXEC)
+
+#define FSACL_gR FSACL_G(FSACL_READ)
+#define FSACL_gW FSACL_G(FSACL_WRITE)
+#define FSACL_gX FSACL_G(FSACL_EXEC)
+
+#define FSACL_oR FSACL_O(FSACL_READ)
+#define FSACL_oW FSACL_O(FSACL_WRITE)
+#define FSACL_oX FSACL_O(FSACL_EXEC)
+
+// permitted read (any usr or group matched)
+#define FSACL_RD (FSACL_uRD | FSACL_gRD)
+// permitted write (any usr or group matched)
+#define FSACL_WR (FSACL_uWR | FSACL_gWR)
+// permitted execute (any usr or group matched)
+#define FSACL_X (FSACL_uX | FSACL_gX)
+
+#define FSACL_u_ 0
+#define FSACL_g_ 0
+#define FSACL_o_ 0
+
+// any read
+#define FSACL_aR (FSACL_uR | FSACL_gR | FSACL_oR)
+// any write
+#define FSACL_aW (FSACL_uW | FSACL_gW | FSACL_oW)
+// any execute
+#define FSACL_aX (FSACL_uX | FSACL_gX | FSACL_oX)
+
+#define __fsacl_sel(scope, type) (FSACL_##scope##type)
+#define FSACL_u(r, w, x) \
+ (v__(__fsacl_sel(u, r)) | v__(__fsacl_sel(u, w)) | v__(__fsacl_sel(u, x)))
+
+#define FSACL_g(r, w, x) \
+ (v__(__fsacl_sel(g, r)) | v__(__fsacl_sel(g, w)) | v__(__fsacl_sel(g, x)))
+
+#define FSACL_o(r, w, x) \
+ (v__(__fsacl_sel(o, r)) | v__(__fsacl_sel(o, w)) | v__(__fsacl_sel(o, x)))
+
+static inline bool must_inline
+fsacl_allow_ops(unsigned int ops, unsigned int acl, uid_t uid, gid_t gid)
+{
+ return !!(acl & ops & check_current_acl(uid, gid));
+}
+
+#endif /* __LUNAIX_FS_ACL_H */
{
inode->ops = &devfs_inode_ops;
inode->default_fops = &devfs_file_ops;
+
+ // we set default access right to be 0660.
+ // TODO need a way to allow this to be changed
+
+ fsapi_inode_setaccess(inode, FSACL_u(R, W, _) | FSACL_g(R, W, _));
+ fsapi_inode_setowner(inode, 0, 0);
}
int
goto done;
}
- if ((errno = vfs_open(dnode, &file))) {
+ if (!check_allow_execute(dnode->inode)) {
+ errno = EPERM;
goto done;
}
errno = EISDIR;
goto done;
}
+
+ if ((errno = vfs_open(dnode, &file))) {
+ goto done;
+ }
errno = exec_load(container, file);
#define IMODE_ORD 0x0004
#define IMODE_OWR 0x0002
#define IMODE_OEX 0x0001
+#define IMODE_ACL_MASK 0x01ff
#define ext2_aligned compact align(4)
#define to_ext2ino_id(fsblock_id) ((fsblock_id) + 1)
b_ino->i_mtime,
b_ino->i_atime);
+ fsapi_inode_setaccess(inode, b_ino->i_mode & IMODE_ACL_MASK);
+ fsapi_inode_setowner(inode, b_ino->i_uid,
+ b_ino->i_gid);
+
__ext2ino_fill_common(inode, ino_id);
if (check_itype(b_ino->i_mode, IMODE_IFLNK)) {
#include <klibc/string.h>
-#include <lunaix/fs.h>
+#include <lunaix/fs/api.h>
#include "iso9660.h"
#include <lunaix/mm/cake.h>
#include <lunaix/mm/valloc.h>
inode->ctime = iso9660_dt2unix(&xattr->ctime);
inode->mtime = iso9660_dt2unix(&xattr->mtime);
+ fsapi_inode_setaccess(inode, xattr->perm);
+ fsapi_inode_setowner(inode, xattr->owner.le, xattr->group.le);
+
inode->lb_addr += dir->xattr_len * dir->fu_size;
vfree(xattr);
}
+ else {
+ fsapi_inode_setaccess(inode, FSACL_u(R, W, _) | FSACL_g(R, W, _));
+ fsapi_inode_setowner(inode, 0, 0);
+ }
inode->ctime = dir->ctime ? dir->ctime : inode->ctime;
inode->mtime = dir->mtime ? dir->mtime : inode->mtime;
time_t ctime;
time_t atime;
time_t mtime;
+
struct hstr name;
char name_val[ISO9660_IDLEN];
};
if ((dnode->mnt->flags & MNT_RO)) {
return EROFS;
}
+
+ if (!check_allow_write(dnode->inode)) {
+ return EPERM;
+ }
+
return 0;
}
{
inode->ops = (struct v_inode_ops*)&twifs_inode_ops;
inode->default_fops = (struct v_file_ops*)&twifs_file_ops;
+
+
+ // we set default access right to be 0660.
+ // TODO need a way to allow this to be changed
+
+ fsapi_inode_setaccess(inode, FSACL_u(R, W, _) | FSACL_g(R, W, _));
+ fsapi_inode_setowner(inode, 0, 0);
}
int
int
vfs_open(struct v_dnode* dnode, struct v_file** file)
{
- if (!dnode->inode || !dnode->inode->ops->open) {
+ struct v_inode* inode = dnode->inode;
+
+ if (!inode || !inode->ops->open) {
return ENOTSUP;
}
- struct v_inode* inode = dnode->inode;
-
lock_inode(inode);
struct v_file* vfile = cake_grab(file_pile);
goto done;
}
+ if (!check_allow_read(file->inode)) {
+ errno = EPERM;
+ goto done;
+ }
+
lock_inode(file->inode);
file->inode->atime = clock_unixtime();
goto done;
}
+ if (!check_allow_read(inode)) {
+ errno = EPERM;
+ goto done;
+ }
+
lock_inode(inode);
int overflow = 0;
return ENOTSUP;
}
+ if (!check_allow_read(inode)) {
+ return EPERM;
+ }
+
lock_inode(inode);
int errno = inode->ops->read_symlink(inode, &link);
}
__dup_fdtable(pcb);
+ uscope_copy(&pcb->uscope, current_user_scope());
struct proc_mm* mm = vmspace(pcb);
procvm_dupvms_mount(mm);
static inline void
__ref_groups_obj(struct ugroup_obj* ugo)
{
+ if (unlikely(!ugo)) {
+ return;
+ }
+
ugo->refs++;
}