Security analysis of virtio-fs functions #10
dimakuv
started this conversation in
Security analysis
Replies: 0 comments
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
-
DISCLAIMER: THIS DESCRIPTION IS OLD, SOME FUNCTIONS ETC. MAY HAVE CHANGED/WERE ADDED!
General notes
virtio_fs_exec_request()
for code.fuse_out_header::unique
field is not used at all.FUSE_INIT
Signature:
int virtio_fs_fuse_init(void)
7.31
. Nothing secret here.7.9
(due to compatibility issues).fuse_init_out
. So no possibility of attacks.FUSE_LOOKUP
Signature:
int virtio_fs_fuse_lookup(const char* filename, uint64_t* out_nodeid)
filename
-- needs to be seen by VMM, no secret leak.out_nodeid
-- opaque number; doesn't affect control flow in any of the callers; used purely as an opaque input to other FUSE ops.FUSE_READLINK
Signature:
int virtio_fs_fuse_readlink(uint64_t nodeid, uint64_t size, char* out_buf, uint64_t* out_size)
nodeid
-- opaque number as reported byvirtio_fs_fuse_lookup()
, no secret.size
-- size of the buffer that will hold the link path, no secret.out_buf
-- buffer in which the link path will be copied into; a bounce buffer is used to not overwrite this buffer contents until the FUSE op finishes successfully. The number of copied bytes is verified to not exceedsize
.out_size
-- the number of copied bytes; verified to not exceedsize
.FUSE_OPEN
Signature:
int virtio_fs_fuse_open(uint64_t nodeid, uint32_t flags, uint64_t* out_fh)
nodeid
-- opaque number as reported byvirtio_fs_fuse_lookup()
, no secret.flags
-- flags to open the file, no secret.out_fh
-- opaque identifier (file handle) used by the FUSE server; doesn't affect control flow in any of the callers; used purely as an opaque input to other FUSE ops.FUSE_CREATE
Signature:
FUSE_CREATE
is a sum of three operations: file creation +FUSE_LOOKUP
+FUSE_OPEN
.dir_nodeid
-- opaque number as reported byvirtio_fs_fuse_lookup()
, no secret.filename
-- base name of the to-be-created file, no secret.flags
-- flags to open the file, no secret.mode
-- permissions with which to create the file, no secret.out_nodeid
-- opaque number; doesn't affect control flow in any of the callers; used purely as an opaque input to other FUSE ops.out_fh
-- opaque identifier (file handle) used by the FUSE server; doesn't affect control flow in any of the callers; used purely as an opaque input to other FUSE ops.FUSE_RELEASE
Signature:
int virtio_fs_fuse_release(uint64_t nodeid, uint64_t fh)
This FUSE operation doesn't update any Gramine state, so no possibility of attacks.
FUSE_UNLINK
Signature:
int virtio_fs_fuse_unlink(uint64_t dir_nodeid, const char* filename)
This FUSE operation doesn't update any Gramine state, so no possibility of attacks.
FUSE_RENAME
Signature:
This FUSE operation doesn't update any Gramine state, so no possibility of attacks.
FUSE_READ
Signature:
nodeid
-- opaque number as reported byvirtio_fs_fuse_lookup()
, no secret.fh
-- opaque identifier (file handle) as reported byvirtio_fs_fuse_open()
; no secret.size
-- size of the buffer to fill, no secret.offset
-- offset in the host file to read from, no secret.out_buf
-- buffer in which the file contents are copied into. This buffer is zeroed-out in case of any failures (to not accidentally transfer malicious data into the Gramine TD). The number of copied bytes is verified to not exceedsize
.out_size
-- the number of copied bytes; verified to not exceedsize
.FUSE_WRITE
Signature:
nodeid
-- opaque number as reported byvirtio_fs_fuse_lookup()
, no secret.fh
-- opaque identifier (file handle) as reported byvirtio_fs_fuse_open()
; no secret.buf
-- buffer from which the file contents are copied from. Buffer contents are either encrypted (in case of Protected Files) or don't matter (in case of Allowed Files). The number of copied-out bytes is verified to not exceedsize
.size
-- size of the buffer, no secret.offset
-- offset in the host file to write to, no secret.out_size
-- the number of copied bytes; verified to not exceedsize
.FUSE_FLUSH
Signature:
int virtio_fs_fuse_flush(uint64_t nodeid, uint64_t fh)
This FUSE operation doesn't update any Gramine state, so no possibility of attacks.
FUSE_GETATTR
Signature:
nodeid
-- opaque number as reported byvirtio_fs_fuse_lookup()
, no secret.fh
-- opaque identifier (file handle) as reported byvirtio_fs_fuse_open()
; no secret.flags
-- alwaysFUSE_GETATTR_FH
in current Gramine code. Signifies that the file was opened. No secret.max_size
-- maximum size of the file that the caller is ready to accept. This may beUINT64_MAX
if the caller is fine with any file size, or some smaller limit so that the caller can e.g. safelymalloc()
such size -- for example, reading the manifest limits the manifest file size to 1GB.out_attr
-- file attributes. Onlysize
andmode
are used (size can be limited bymax_size
, andmode
is limited to regular files and dirs). All other file attributes are unused and are zeroed out for security.FUSE_SETATTR
Signature:
int virtio_fs_fuse_setattr(uint64_t nodeid, const struct fuse_setattr_in* setattr)
nodeid
-- opaque number as reported byvirtio_fs_fuse_lookup()
, no secret.setattr
-- file attributes to set. Currently only size (FATTR_SIZE
) and mode/permissions (FATTR_MODE
) are set by Gramine.This FUSE operation doesn't update any Gramine state, so no possibility of attacks.
FUSE_OPENDIR
Signature:
int virtio_fs_fuse_opendir(uint64_t nodeid, uint32_t flags, uint64_t* out_fh)
nodeid
-- opaque number as reported byvirtio_fs_fuse_lookup()
, no secret.flags
-- flags to open the dir, no secret.out_fh
-- opaque identifier (dir handle) used by the FUSE server; doesn't affect control flow in any of the callers; used purely as an opaque input to other FUSE ops.This function has exactly the same properties as
FUSE_OPEN
.FUSE_MKDIR
Signature:
dir_nodeid
-- opaque number as reported byvirtio_fs_fuse_lookup()
, no secret.dirname
-- base name of the to-be-created dir, no secret.mode
-- permissions with which to create the dir, no secret.out_nodeid
-- opaque number; doesn't affect control flow in any of the callers; used purely as an opaque input to other FUSE ops.This function is very similar in its properties to
FUSE_CREATE
.FUSE_RELEASEDIR
Signature:
int virtio_fs_fuse_releasedir(uint64_t nodeid, uint64_t fh)
This FUSE operation doesn't update any Gramine state, so no possibility of attacks. This function has exactly the same properties as
FUSE_RELEASE
.FUSE_RMDIR
Signature:
int virtio_fs_fuse_rmdir(uint64_t dir_nodeid, const char* dirname)
This FUSE operation doesn't update any Gramine state, so no possibility of attacks. This function has exactly the same properties as
FUSE_UNLINK
.FUSE_READDIR
Signature:
nodeid
-- opaque number as reported byvirtio_fs_fuse_lookup()
, no secret.fh
-- opaque identifier (dir handle) as reported byvirtio_fs_fuse_open()
; no secret.size
-- size of the buffer to fill, no secret.offset
-- offset in the host dir to read from, no secret.out_dirents
-- buffer in which the dir contents (directory entries) are copied into. This buffer is zeroed-out in case of any failures (to not accidentally transfer malicious data into the Gramine TD). The number of copied bytes is verified to not exceedsize
.out_size
-- the number of copied bytes; verified to not exceedsize
.This FUSE operation is very similar to
FUSE_READ
.Beta Was this translation helpful? Give feedback.
All reactions