Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F153708821
D19548.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
12 KB
Referenced Files
None
Subscribers
None
D19548.diff
View Options
Index: head/lib/libcasper/services/cap_fileargs/cap_fileargs.h
===================================================================
--- head/lib/libcasper/services/cap_fileargs/cap_fileargs.h
+++ head/lib/libcasper/services/cap_fileargs/cap_fileargs.h
@@ -36,16 +36,21 @@
#include <stdbool.h>
+#define FA_OPEN 1
+#define FA_LSTAT 2
+
#ifdef WITH_CASPER
struct fileargs;
typedef struct fileargs fileargs_t;
+struct stat;
fileargs_t *fileargs_init(int argc, char *argv[], int flags, mode_t mode,
- cap_rights_t *rightsp);
+ cap_rights_t *rightsp, int operations);
fileargs_t *fileargs_cinit(cap_channel_t *cas, int argc, char *argv[],
- int flags, mode_t mode, cap_rights_t *rightsp);
+ int flags, mode_t mode, cap_rights_t *rightsp, int operations);
fileargs_t *fileargs_initnv(nvlist_t *limits);
fileargs_t *fileargs_cinitnv(cap_channel_t *cas, nvlist_t *limits);
+int fileargs_lstat(fileargs_t *fa, const char *name, struct stat *sb);
int fileargs_open(fileargs_t *fa, const char *name);
void fileargs_free(fileargs_t *fa);
FILE *fileargs_fopen(fileargs_t *fa, const char *name, const char *mode);
@@ -57,7 +62,7 @@
static inline fileargs_t *
fileargs_init(int argc __unused, char *argv[] __unused, int flags, mode_t mode,
- cap_rights_t *rightsp __unused) {
+ cap_rights_t *rightsp __unused, int operations __unused) {
fileargs_t *fa;
fa = malloc(sizeof(*fa));
@@ -71,10 +76,10 @@
static inline fileargs_t *
fileargs_cinit(cap_channel_t *cas __unused, int argc, char *argv[], int flags,
- mode_t mode, cap_rights_t *rightsp)
+ mode_t mode, cap_rights_t *rightsp, int operations)
{
- return (fileargs_init(argc, argv, flags, mode, rightsp));
+ return (fileargs_init(argc, argv, flags, mode, rightsp, operations));
}
static inline fileargs_t *
@@ -85,7 +90,8 @@
fa = fileargs_init(0, NULL,
nvlist_get_number(limits, "flags"),
dnvlist_get_number(limits, "mode", 0),
- NULL);
+ NULL,
+ nvlist_get_number(limits, "operations"));
nvlist_destroy(limits);
return (fa);
@@ -98,6 +104,8 @@
return (fileargs_initnv(limits));
}
+#define fileargs_lstat(fa, name, sb) \
+ lstat(name, sb)
#define fileargs_open(fa, name) \
open(name, fa->fa_flags, fa->fa_mode)
#define fileargs_fopen(fa, name, mode) \
Index: head/lib/libcasper/services/cap_fileargs/cap_fileargs.3
===================================================================
--- head/lib/libcasper/services/cap_fileargs/cap_fileargs.3
+++ head/lib/libcasper/services/cap_fileargs/cap_fileargs.3
@@ -24,7 +24,7 @@
.\"
.\" $FreeBSD$
.\"
-.Dd November 12, 2018
+.Dd April 17, 2019
.Dt CAP_FILEARGS 3
.Os
.Sh NAME
@@ -33,6 +33,7 @@
.Nm fileargs_init ,
.Nm fileargs_initnv ,
.Nm fileargs_free ,
+.Nm fileargs_lstat ,
.Nm fileargs_open ,
.Nm fileargs_fopen
.Nd "library for handling files in capability mode"
@@ -43,9 +44,9 @@
.In libcasper.h
.In casper/cap_fileargs.h
.Ft "fileargs_t *"
-.Fn fileargs_init "int argc" "char *argv[]" "int flags" "mode_t mode" "cap_rights_t *rightsp"
+.Fn fileargs_init "int argc" "char *argv[]" "int flags" "mode_t mode" "cap_rights_t *rightsp" "int operations"
.Ft "fileargs_t *"
-.Fn fileargs_cinit "cap_channel_t *cas" "int argc" "char *argv[]" "int flags" "mode_t mode" "cap_rights_t *rightsp"
+.Fn fileargs_cinit "cap_channel_t *cas" "int argc" "char *argv[]" "int flags" "mode_t mode" "cap_rights_t *rightsp" "int operations"
.Ft "fileargs_t *"
.Fn fileargs_cinitnv "cap_channel_t *cas" "nvlist_t *limits"
.Ft "fileargs_t *"
@@ -53,6 +54,8 @@
.Ft "void"
.Fn fileargs_free "fileargs_t *fa"
.Ft "int"
+.Fn fileargs_lstat "fileargs_t *fa" "const char *path" "struct stat *sb"
+.Ft "int"
.Fn fileargs_open "fileargs_t *fa" "const char *name"
.Ft "FILE *"
.Fn fileargs_fopen "fileargs_t *fa" "const char *name" "const char *mode"
@@ -97,6 +100,22 @@
argument contains a list of the capability rights which file should be limited to.
For more details of the capability rights see
.Xr cap_rights_init 3 .
+The
+.Fa operations
+argument limits the operations that are available using
+.Nm system.fileargs .
+.Fa operations
+is a combination of:
+.Bl -ohang -offset indent
+.It FA_OPEN
+Allow
+.Fn fileargs_open
+and
+.Fn fileargs_fopen .
+.It FA_LSTAT
+Allow
+.Fn fileargs_lstat .
+.El
.Pp
The function
.Fn fileargs_cinit
@@ -126,6 +145,11 @@
.Dv NULL
argument.
.Pp
+The function
+.Fn fileargs_lstat
+is equivalent to
+.Xr lstat 2 .
+.Pp
The functions
.Fn fileargs_open
and
@@ -165,6 +189,15 @@
The
.Va mode
argument tells which what mode file should be created.
+.It operations (NV_TYPE_NUMBER)
+The
+.Va operations
+limits the usable operations for
+.Fa system.fileargs .
+The possible values are explained as
+.Va operations
+argument with
+.Fn fileargs_init .
.El
.Pp
The
@@ -201,7 +234,7 @@
/* Create capability to the system.fileargs service. */
fa = fileargs_init(argc, argv, O_RDONLY, 0,
- cap_rights_init(&rights, CAP_READ));
+ cap_rights_init(&rights, CAP_READ), FA_OPEN);
if (fa == NULL)
err(1, "unable to open system.fileargs service");
@@ -222,6 +255,7 @@
.Ed
.Sh SEE ALSO
.Xr cap_enter 2 ,
+.Xr lstat 2 ,
.Xr open 2 ,
.Xr cap_rights_init 3 ,
.Xr err 3 ,
Index: head/lib/libcasper/services/cap_fileargs/cap_fileargs.c
===================================================================
--- head/lib/libcasper/services/cap_fileargs/cap_fileargs.c
+++ head/lib/libcasper/services/cap_fileargs/cap_fileargs.c
@@ -35,6 +35,7 @@
#include <sys/cnv.h>
#include <sys/dnv.h>
#include <sys/nv.h>
+#include <sys/stat.h>
#include <assert.h>
#include <errno.h>
@@ -59,8 +60,37 @@
};
static int
-fileargs_get_cache(fileargs_t *fa, const char *name)
+fileargs_get_lstat_cache(fileargs_t *fa, const char *name, struct stat *sb)
{
+ const nvlist_t *nvl;
+ size_t size;
+ const void *buf;
+
+ assert(fa != NULL);
+ assert(fa->fa_magic == FILEARGS_MAGIC);
+ assert(name != NULL);
+
+ if (fa->fa_cache == NULL)
+ return (-1);
+
+ nvl = dnvlist_get_nvlist(fa->fa_cache, name, NULL);
+ if (nvl == NULL)
+ return (-1);
+
+ if (!nvlist_exists_binary(nvl, "stat")) {
+ return (-1);
+ }
+
+ buf = nvlist_get_binary(nvl, "stat", &size);
+ assert(size == sizeof(*sb));
+ memcpy(sb, buf, size);
+
+ return (0);
+}
+
+static int
+fileargs_get_fd_cache(fileargs_t *fa, const char *name)
+{
int fd;
const nvlist_t *nvl;
nvlist_t *tnvl;
@@ -80,6 +110,12 @@
return (-1);
tnvl = nvlist_take_nvlist(fa->fa_cache, name);
+
+ if (!nvlist_exists_descriptor(tnvl, "fd")) {
+ nvlist_destroy(tnvl);
+ return (-1);
+ }
+
fd = nvlist_take_descriptor(tnvl, "fd");
nvlist_destroy(tnvl);
@@ -102,7 +138,7 @@
}
static nvlist_t*
-fileargs_fetch(fileargs_t *fa, const char *name)
+fileargs_fetch(fileargs_t *fa, const char *name, const char *cmd)
{
nvlist_t *nvl;
int serrno;
@@ -111,7 +147,7 @@
assert(name != NULL);
nvl = nvlist_create(NV_FLAG_NO_UNIQUE);
- nvlist_add_string(nvl, "cmd", "open");
+ nvlist_add_string(nvl, "cmd", cmd);
nvlist_add_string(nvl, "name", name);
nvl = cap_xfer_nvlist(fa->fa_chann, nvl);
@@ -130,7 +166,7 @@
static nvlist_t *
fileargs_create_limit(int argc, const char * const *argv, int flags,
- mode_t mode, cap_rights_t *rightsp)
+ mode_t mode, cap_rights_t *rightsp, int operations)
{
nvlist_t *limits;
int i;
@@ -140,6 +176,7 @@
return (NULL);
nvlist_add_number(limits, "flags", flags);
+ nvlist_add_number(limits, "operations", operations);
if (rightsp != NULL) {
nvlist_add_binary(limits, "cap_rights", rightsp,
sizeof(*rightsp));
@@ -172,7 +209,7 @@
fileargs_t *
fileargs_init(int argc, char *argv[], int flags, mode_t mode,
- cap_rights_t *rightsp)
+ cap_rights_t *rightsp, int operations)
{
nvlist_t *limits;
@@ -181,7 +218,7 @@
}
limits = fileargs_create_limit(argc, (const char * const *)argv, flags,
- mode, rightsp);
+ mode, rightsp, operations);
if (limits == NULL)
return (NULL);
@@ -190,7 +227,7 @@
fileargs_t *
fileargs_cinit(cap_channel_t *cas, int argc, char *argv[], int flags,
- mode_t mode, cap_rights_t *rightsp)
+ mode_t mode, cap_rights_t *rightsp, int operations)
{
nvlist_t *limits;
@@ -199,7 +236,7 @@
}
limits = fileargs_create_limit(argc, (const char * const *)argv, flags,
- mode, rightsp);
+ mode, rightsp, operations);
if (limits == NULL)
return (NULL);
@@ -234,7 +271,7 @@
cap_channel_t *chann;
fileargs_t *fa;
int serrno, ret;
- int flags;
+ int flags, operations;
assert(cas != NULL);
@@ -252,6 +289,7 @@
}
flags = nvlist_get_number(limits, "flags");
+ operations = nvlist_get_number(limits, "operations");
/* Limits are consumed no need to free them. */
ret = cap_limit_set(chann, limits);
@@ -291,11 +329,11 @@
return (-1);
}
- fd = fileargs_get_cache(fa, name);
+ fd = fileargs_get_fd_cache(fa, name);
if (fd != -1)
return (fd);
- nvl = fileargs_fetch(fa, name);
+ nvl = fileargs_fetch(fa, name, "open");
if (nvl == NULL)
return (-1);
@@ -322,6 +360,53 @@
return (fdopen(fd, mode));
}
+int
+fileargs_lstat(fileargs_t *fa, const char *name, struct stat *sb)
+{
+ nvlist_t *nvl;
+ const void *buf;
+ size_t size;
+ char *cmd;
+
+ assert(fa != NULL);
+ assert(fa->fa_magic == FILEARGS_MAGIC);
+
+ if (name == NULL) {
+ errno = EINVAL;
+ return (-1);
+ }
+
+ if (sb == NULL) {
+ errno = EFAULT;
+ return (-1);
+ }
+
+ if (fa->fa_chann == NULL) {
+ errno = ENOTCAPABLE;
+ return (-1);
+ }
+
+ if (fileargs_get_lstat_cache(fa, name, sb) != -1)
+ return (0);
+
+ nvl = fileargs_fetch(fa, name, "lstat");
+ if (nvl == NULL)
+ return (-1);
+
+ buf = nvlist_get_binary(nvl, "stat", &size);
+ assert(size == sizeof(*sb));
+ memcpy(sb, buf, size);
+
+ cmd = nvlist_take_string(nvl, "cmd");
+ if (strcmp(cmd, "cache") == 0)
+ fileargs_set_cache(fa, nvl);
+ else
+ nvlist_destroy(nvl);
+ free(cmd);
+
+ return (0);
+}
+
void
fileargs_free(fileargs_t *fa)
{
@@ -348,6 +433,7 @@
static bool allcached;
static const cap_rights_t *caprightsp;
static int capflags;
+static int allowed_operations;
static mode_t capmode;
static int
@@ -382,6 +468,7 @@
void *cookie;
nvlist_t *new;
const char *fname;
+ struct stat sb;
if ((capflags & O_CREAT) != 0) {
allcached = true;
@@ -409,14 +496,25 @@
continue;
}
- fd = open_file(fname);
- if (fd < 0) {
- i--;
- continue;
+ new = nvlist_create(NV_FLAG_NO_UNIQUE);
+ if ((allowed_operations & FA_OPEN) != 0) {
+ fd = open_file(fname);
+ if (fd < 0) {
+ i--;
+ nvlist_destroy(new);
+ continue;
+ }
+ nvlist_move_descriptor(new, "fd", fd);
}
+ if ((allowed_operations & FA_LSTAT) != 0) {
+ if (lstat(fname, &sb) < 0) {
+ i--;
+ nvlist_destroy(new);
+ continue;
+ }
+ nvlist_add_binary(new, "stat", &sb, sizeof(sb));
+ }
- new = nvlist_create(NV_FLAG_NO_UNIQUE);
- nvlist_move_descriptor(new, "fd", fd);
nvlist_add_nvlist(nvlout, fname, new);
}
cacheposition = cookie;
@@ -424,10 +522,13 @@
}
static bool
-fileargs_allowed(const nvlist_t *limits, const nvlist_t *request)
+fileargs_allowed(const nvlist_t *limits, const nvlist_t *request, int operation)
{
const char *name;
+ if ((allowed_operations & operation) == 0)
+ return (false);
+
name = dnvlist_get_string(request, "name", NULL);
if (name == NULL)
return (false);
@@ -450,6 +551,7 @@
return (ENOTCAPABLE);
capflags = (int)dnvlist_get_number(newlimits, "flags", 0);
+ allowed_operations = (int)dnvlist_get_number(newlimits, "operations", 0);
if ((capflags & O_CREAT) != 0)
capmode = (mode_t)nvlist_get_number(newlimits, "mode");
else
@@ -461,6 +563,37 @@
}
static int
+fileargs_command_lstat(const nvlist_t *limits, nvlist_t *nvlin,
+ nvlist_t *nvlout)
+{
+ int stat;
+ const char *name;
+ struct stat sb;
+
+ if (limits == NULL)
+ return (ENOTCAPABLE);
+
+ if (!fileargs_allowed(limits, nvlin, FA_LSTAT))
+ return (ENOTCAPABLE);
+
+ name = nvlist_get_string(nvlin, "name");
+
+ stat = lstat(name, &sb);
+ if (stat < 0)
+ return (errno);
+
+ if (!allcached && (lastname == NULL ||
+ strcmp(name, lastname) == 0)) {
+ nvlist_add_string(nvlout, "cmd", "cache");
+ fileargs_add_cache(nvlout, limits, name);
+ } else {
+ nvlist_add_string(nvlout, "cmd", "lstat");
+ }
+ nvlist_add_binary(nvlout, "stat", &sb, sizeof(sb));
+ return (0);
+}
+
+static int
fileargs_command_open(const nvlist_t *limits, nvlist_t *nvlin,
nvlist_t *nvlout)
{
@@ -470,7 +603,7 @@
if (limits == NULL)
return (ENOTCAPABLE);
- if (!fileargs_allowed(limits, nvlin))
+ if (!fileargs_allowed(limits, nvlin, FA_OPEN))
return (ENOTCAPABLE);
name = nvlist_get_string(nvlin, "name");
@@ -497,6 +630,9 @@
if (strcmp(cmd, "open") == 0)
return (fileargs_command_open(limits, nvlin, nvlout));
+
+ if (strcmp(cmd, "lstat") == 0)
+ return (fileargs_command_lstat(limits, nvlin, nvlout));
return (EINVAL);
}
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Fri, Apr 24, 2:49 AM (1 h, 21 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
32056714
Default Alt Text
D19548.diff (12 KB)
Attached To
Mode
D19548: Add fileargs_lstat to cap_fileargs service
Attached
Detach File
Event Timeline
Log In to Comment