orscmd: add minimal getcap and setcap tools

These are mostly intended for debugging and for emergency repairs.
Optimized for minimal code size and dependencies, not for usability.

Change-Id: I671850a03151dd716c715f953f0b2bc8dbacffe7
This commit is contained in:
that
2017-01-18 23:34:28 +01:00
committed by Dees Troy
parent 0c347d597a
commit 6b9ad62b6c
+66
View File
@@ -13,12 +13,20 @@
along with TWRP. If not, see <http://www.gnu.org/licenses/>.
*/
#define __STDC_FORMAT_MACROS 1
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <string.h>
#include <fcntl.h>
#include <errno.h>
#include <inttypes.h>
// for setcap and getcap
#include <sys/capability.h>
#include <sys/xattr.h>
#include <linux/xattr.h>
#include "orscmd.h"
#include "../variables.h"
@@ -44,6 +52,45 @@ void print_usage(void) {
printf("\nSee more documentation at http://teamw.in/openrecoveryscript\n");
}
int do_setcap(const char* filename, const char* capabilities)
{
uint64_t caps;
if (sscanf(capabilities, "%" SCNi64, &caps) != 1)
{
printf("setcap: invalid capabilities \"%s\"\n", filename);
return 1;
}
struct vfs_cap_data cap_data;
memset(&cap_data, 0, sizeof(cap_data));
cap_data.magic_etc = VFS_CAP_REVISION | VFS_CAP_FLAGS_EFFECTIVE;
cap_data.data[0].permitted = (uint32_t) (caps & 0xffffffff);
cap_data.data[0].inheritable = 0;
cap_data.data[1].permitted = (uint32_t) (caps >> 32);
cap_data.data[1].inheritable = 0;
if (setxattr(filename, XATTR_NAME_CAPS, &cap_data, sizeof(cap_data), 0) < 0) {
printf("setcap of %s to %" PRIx64 " failed: %s\n",
filename, caps, strerror(errno));
return 1;
}
return 0;
}
int do_getcap(const char* filename)
{
struct vfs_cap_data cap_data;
memset(&cap_data, 0, sizeof(cap_data));
int rc = getxattr(filename, XATTR_NAME_CAPS, &cap_data, sizeof(vfs_cap_data));
if (rc > 0)
{
uint64_t caps = (uint64_t) cap_data.data[1].permitted << 32 | cap_data.data[0].permitted;
printf("0x%" PRIx64 "\n", caps);
}
else
printf("getcap of %s failed: %s\n", filename, strerror(errno));
return rc > 0;
}
int main(int argc, char **argv) {
int read_fd, write_fd, index;
char command[1024], result[512];
@@ -57,6 +104,25 @@ int main(int argc, char **argv) {
return 0;
}
if (strcmp(argv[1], "setcap") == 0) {
if (argc != 4)
{
printf("Usage: setcap filename capabilities\n\n"
"capabilities must be specified as a number. Prefix with 0x for hexadecimal.\n");
return 1;
}
return do_setcap(argv[2], argv[3]);
}
if (strcmp(argv[1], "getcap") == 0) {
if (argc != 3)
{
printf("Usage: getcap filename\n");
return 1;
}
return do_getcap(argv[2]);
}
sprintf(command, "%s", argv[1]);
for (index = 2; index < argc; index++) {
sprintf(command, "%s %s", command, argv[index]);