diff options
author | Tom Cherry <tomcherry@google.com> | 2016-02-17 16:27:08 -0800 |
---|---|---|
committer | Rob Landley <rob@landley.net> | 2016-02-17 19:02:01 -0600 |
commit | b66a29ab58c686c98ab9683c5c544f40a1ea35f5 (patch) | |
tree | 11a5730a48e160a4b895584f956e81b046eaa156 | |
parent | 289ca9b68c5bb10c3dda8aa71ae1bbe9dbc98ae7 (diff) | |
download | toybox-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.c | 63 |
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); } |