aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTom Cherry <tomcherry@google.com>2016-02-17 16:27:08 -0800
committerRob Landley <rob@landley.net>2016-02-17 19:02:01 -0600
commitb66a29ab58c686c98ab9683c5c544f40a1ea35f5 (patch)
tree11a5730a48e160a4b895584f956e81b046eaa156
parent289ca9b68c5bb10c3dda8aa71ae1bbe9dbc98ae7 (diff)
downloadtoybox-b66a29ab58c686c98ab9683c5c544f40a1ea35f5.tar.gz
Add support for getprop -Z
Add support for a -Z option to getprop that will either print the SELabel of a given property if one is provided or print all properties that have been set along with their SELabel. Also, correct a memory leak when freeing TT.nv.
-rw-r--r--toys/android/getprop.c63
1 files changed, 58 insertions, 5 deletions
diff --git a/toys/android/getprop.c b/toys/android/getprop.c
index 09bb0f0b..cce53a6d 100644
--- a/toys/android/getprop.c
+++ b/toys/android/getprop.c
@@ -2,7 +2,7 @@
*
* Copyright 2015 The Android Open Source Project
-USE_GETPROP(NEWTOY(getprop, ">2", TOYFLAG_USR|TOYFLAG_SBIN))
+USE_GETPROP(NEWTOY(getprop, ">2Z", TOYFLAG_USR|TOYFLAG_SBIN))
config GETPROP
bool "getprop"
@@ -19,30 +19,83 @@ config GETPROP
#include <cutils/properties.h>
+#include <selinux/android.h>
+#include <selinux/label.h>
+#include <selinux/selinux.h>
+
GLOBALS(
size_t size;
char **nv; // name/value pairs: even=name, odd=value
+ struct selabel_handle *handle;
)
+static char *get_property_context(char *property)
+{
+ char *context = NULL;
+
+ if (selabel_lookup(TT.handle, &context, property, 1)) {
+ perror_exit("unable to lookup label for \"%s\"", property);
+ }
+ return context;
+}
+
static void add_property(char *name, char *value, void *unused)
{
if (!(TT.size&31)) TT.nv = xrealloc(TT.nv, (TT.size+32)*2*sizeof(char *));
TT.nv[2*TT.size] = xstrdup(name);
- TT.nv[1+2*TT.size++] = xstrdup(value);
+ if (toys.optflags & FLAG_Z) {
+ TT.nv[1+2*TT.size++] = get_property_context(name);
+ } else {
+ TT.nv[1+2*TT.size++] = xstrdup(value);
+ }
+}
+
+// Needed to supress extraneous "Loaded property_contexts from" message
+int selinux_log_callback(int type, const char *fmt, ...) {
+ va_list ap;
+
+ if (type == SELINUX_INFO) return 0;
+ va_start(ap, fmt);
+ verror_msg(fmt, 0, ap);
+ va_end(ap);
+ return 0;
}
void getprop_main(void)
{
+ if (toys.optflags & FLAG_Z) {
+ union selinux_callback cb;
+
+ cb.func_log = selinux_log_callback;
+ selinux_set_callback(SELINUX_CB_LOG, cb);
+ TT.handle = selinux_android_prop_context_handle();
+ if (!TT.handle) error_exit("unable to get selinux property context handle");
+ }
+
if (*toys.optargs) {
- property_get(*toys.optargs, toybuf, toys.optargs[1] ? toys.optargs[1] : "");
- puts(toybuf);
+ if (toys.optflags & FLAG_Z) {
+ char *context = get_property_context(*toys.optargs);
+
+ puts(context);
+ if (CFG_TOYBOX_FREE) free(context);
+ } else {
+ property_get(*toys.optargs, toybuf, toys.optargs[1] ? toys.optargs[1] : "");
+ puts(toybuf);
+ }
} else {
size_t i;
if (property_list((void *)add_property, 0)) error_exit("property_list");
qsort(TT.nv, TT.size, 2*sizeof(char *), qstrcmp);
for (i = 0; i<TT.size; i++) printf("[%s]: [%s]\n", TT.nv[i*2],TT.nv[1+i*2]);
- if (CFG_TOYBOX_FREE) free(TT.nv);
+ if (CFG_TOYBOX_FREE) {
+ for (i = 0; i<TT.size; i++) {
+ free(TT.nv[i*2]);
+ free(TT.nv[1+i*2]);
+ }
+ free(TT.nv);
+ }
}
+ if (CFG_TOYBOX_FREE && (toys.optflags & FLAG_Z)) selabel_close(TT.handle);
}