summaryrefslogtreecommitdiffstats
path: root/svm
diff options
context:
space:
mode:
authorDave Barach <dave@barachs.net>2016-05-31 14:05:46 -0400
committerKeith Burns <alagalah@gmail.com>2016-06-01 19:21:58 +0000
commitdb0cf7963b971ebb393d105a0a29fa7bd926521c (patch)
tree054988a44b4a68ad0e1b4470dfc566dc3e6dfd8a /svm
parent8d9e80583fbb8ffb30e63153ef5b2b21c6b336fa (diff)
VPP-83 Allow non-privileged clients to use the vpp binary API.
Use the command line argument "api-segment { uid <nnn> gid <nnn> }" to configure shared memory segment file ownership. Defaults to uid = gid = 0. Shared-memory segments are explicitly set to 0770 mode, aka "rwxrwx---". Change-Id: Ic5d596b68139add61e7de6ace035c57dfd030111 Signed-off-by: Dave Barach <dave@barachs.net>
Diffstat (limited to 'svm')
-rw-r--r--svm/svm.c26
-rw-r--r--svm/svm.h4
2 files changed, 23 insertions, 7 deletions
diff --git a/svm/svm.c b/svm/svm.c
index 62f317aafb4..b50aa8207ef 100644
--- a/svm/svm.c
+++ b/svm/svm.c
@@ -391,6 +391,11 @@ void *svm_map_region (svm_map_region_args_t *a)
svm_fd = shm_open((char *) shm_name, O_RDWR | O_CREAT | O_EXCL, 0777);
if (svm_fd >= 0) {
+ if (fchmod (svm_fd, 0770) < 0)
+ clib_unix_warning ("segment chmod");
+ /* This turns out to fail harmlessly if the client starts first */
+ if (fchown (svm_fd, a->uid, a->gid) < 0)
+ clib_unix_warning ("segment chown [ok if client starts first]");
vec_free(shm_name);
@@ -615,18 +620,19 @@ static void svm_mutex_cleanup (void)
}
}
-static void svm_region_init_internal (char *root_path)
+static void svm_region_init_internal (char *root_path, int uid, int gid)
{
svm_region_t *rp;
- svm_map_region_args_t *a=0;
+ svm_map_region_args_t _a, *a=&_a;
u64 ticks = clib_cpu_time_now();
uword randomize_baseva;
/* guard against klutz calls */
- root_rp_refcount++;
if (root_rp)
return;
+ root_rp_refcount++;
+
atexit(svm_mutex_cleanup);
/* Randomize the shared-VM base at init time */
@@ -635,12 +641,14 @@ static void svm_region_init_internal (char *root_path)
else
randomize_baseva = (ticks & 3) * MMAP_PAGESIZE;
- vec_validate(a,0);
+ memset (a, 0, sizeof (*a));
a->root_path = root_path;
a->name = SVM_GLOBAL_REGION_NAME;
a->baseva = SVM_GLOBAL_REGION_BASEVA + randomize_baseva;
a->size = SVM_GLOBAL_REGION_SIZE;
a->flags = SVM_FLAGS_NODATA;
+ a->uid = uid;
+ a->gid = gid;
rp = svm_map_region (a);
ASSERT(rp);
@@ -663,18 +671,22 @@ static void svm_region_init_internal (char *root_path)
svm_pop_heap (oldheap);
}
region_unlock(rp);
- vec_free (a);
root_rp = rp;
}
void svm_region_init (void)
{
- svm_region_init_internal (0);
+ svm_region_init_internal (0, 0 /* uid */, 0 /* gid */);
}
void svm_region_init_chroot (char *root_path)
{
- svm_region_init_internal (root_path);
+ svm_region_init_internal (root_path, 0 /* uid */, 0 /* gid */);
+}
+
+void svm_region_init_chroot_uid_gid (char *root_path, int uid, int gid)
+{
+ svm_region_init_internal (root_path, uid, gid);
}
void *svm_region_find_or_create (svm_map_region_args_t *a)
diff --git a/svm/svm.h b/svm/svm.h
index 5f112cb83dc..bca23792059 100644
--- a/svm/svm.h
+++ b/svm/svm.h
@@ -74,6 +74,9 @@ typedef struct svm_map_region_args_ {
uword flags;
char *backing_file;
uword backing_mmap_size;
+ /* uid, gid to own the svm region(s) */
+ int uid;
+ int gid;
} svm_map_region_args_t;
@@ -108,6 +111,7 @@ typedef struct {
void *svm_region_find_or_create (svm_map_region_args_t *a);
void svm_region_init(void);
void svm_region_init_chroot(char *root_path);
+void svm_region_init_chroot_uid_gid(char *root_path, int uid, int gid);
void svm_region_exit (void);
void svm_region_unmap(void *rp_arg);
void svm_client_scan (char *root_path);