Skip to content

Commit 1ea9fce

Browse files
Jean-Baptiste Queruandroid code review
Jean-Baptiste Queru
authored and
android code review
committed
Merge "Extend toolbox with SE Android support."
2 parents 9355307 + 8290d10 commit 1ea9fce

12 files changed

+616
-8
lines changed

toolbox/Android.mk

+23
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,21 @@ TOOLS := \
5757
touch \
5858
lsof
5959

60+
ifeq ($(HAVE_SELINUX),true)
61+
62+
TOOLS += \
63+
getenforce \
64+
setenforce \
65+
chcon \
66+
restorecon \
67+
runcon \
68+
getsebool \
69+
setsebool \
70+
load_policy
71+
72+
endif
73+
74+
6075
ifneq (,$(filter userdebug eng,$(TARGET_BUILD_VARIANT)))
6176
TOOLS += r
6277
endif
@@ -68,6 +83,14 @@ LOCAL_SRC_FILES:= \
6883

6984
LOCAL_SHARED_LIBRARIES := libcutils libc libusbhost
7085

86+
ifeq ($(HAVE_SELINUX),true)
87+
88+
LOCAL_CFLAGS += -DHAVE_SELINUX
89+
LOCAL_SHARED_LIBRARIES += libselinux
90+
LOCAL_C_INCLUDES += external/libselinux/include
91+
92+
endif
93+
7194
LOCAL_MODULE:= toolbox
7295

7396
# Including this will define $(intermediates).

toolbox/chcon.c

+25
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
#include <unistd.h>
2+
#include <stdio.h>
3+
#include <stdlib.h>
4+
#include <errno.h>
5+
#include <selinux/selinux.h>
6+
7+
int chcon_main(int argc, char **argv)
8+
{
9+
int rc, i;
10+
11+
if (argc < 3) {
12+
fprintf(stderr, "usage: %s context path...\n", argv[0]);
13+
exit(1);
14+
}
15+
16+
for (i = 2; i < argc; i++) {
17+
rc = setfilecon(argv[i], argv[1]);
18+
if (rc < 0) {
19+
fprintf(stderr, "%s: Could not label %s with %s: %s\n",
20+
argv[0], argv[i], argv[1], strerror(errno));
21+
exit(2);
22+
}
23+
}
24+
exit(0);
25+
}

toolbox/getenforce.c

+30
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
#include <unistd.h>
2+
#include <stdio.h>
3+
#include <stdlib.h>
4+
#include <errno.h>
5+
#include <selinux/selinux.h>
6+
7+
int getenforce_main(int argc, char **argv)
8+
{
9+
int rc;
10+
11+
rc = is_selinux_enabled();
12+
if (rc <= 0) {
13+
printf("Disabled\n");
14+
return 0;
15+
}
16+
17+
rc = security_getenforce();
18+
if (rc < 0) {
19+
fprintf(stderr, "Could not get enforcing status: %s\n",
20+
strerror(errno));
21+
return 2;
22+
}
23+
24+
if (rc)
25+
printf("Enforcing\n");
26+
else
27+
printf("Permissive\n");
28+
29+
return 0;
30+
}

toolbox/getsebool.c

+104
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,104 @@
1+
#include <unistd.h>
2+
#include <stdlib.h>
3+
#include <stdio.h>
4+
#include <getopt.h>
5+
#include <errno.h>
6+
#include <string.h>
7+
#include <selinux/selinux.h>
8+
9+
static void usage(const char *progname)
10+
{
11+
fprintf(stderr, "usage: %s -a or %s boolean...\n", progname, progname);
12+
exit(1);
13+
}
14+
15+
int getsebool_main(int argc, char **argv)
16+
{
17+
int i, get_all = 0, rc = 0, active, pending, len = 0, opt;
18+
char **names;
19+
20+
while ((opt = getopt(argc, argv, "a")) > 0) {
21+
switch (opt) {
22+
case 'a':
23+
if (argc > 2)
24+
usage(argv[0]);
25+
if (is_selinux_enabled() <= 0) {
26+
fprintf(stderr, "%s: SELinux is disabled\n",
27+
argv[0]);
28+
return 1;
29+
}
30+
errno = 0;
31+
rc = security_get_boolean_names(&names, &len);
32+
if (rc) {
33+
fprintf(stderr,
34+
"%s: Unable to get boolean names: %s\n",
35+
argv[0], strerror(errno));
36+
return 1;
37+
}
38+
if (!len) {
39+
printf("No booleans\n");
40+
return 0;
41+
}
42+
get_all = 1;
43+
break;
44+
default:
45+
usage(argv[0]);
46+
}
47+
}
48+
49+
if (is_selinux_enabled() <= 0) {
50+
fprintf(stderr, "%s: SELinux is disabled\n", argv[0]);
51+
return 1;
52+
}
53+
if (!len) {
54+
if (argc < 2)
55+
usage(argv[0]);
56+
len = argc - 1;
57+
names = malloc(sizeof(char *) * len);
58+
if (!names) {
59+
fprintf(stderr, "%s: out of memory\n", argv[0]);
60+
return 2;
61+
}
62+
for (i = 0; i < len; i++) {
63+
names[i] = strdup(argv[i + 1]);
64+
if (!names[i]) {
65+
fprintf(stderr, "%s: out of memory\n",
66+
argv[0]);
67+
return 2;
68+
}
69+
}
70+
}
71+
72+
for (i = 0; i < len; i++) {
73+
active = security_get_boolean_active(names[i]);
74+
if (active < 0) {
75+
if (get_all && errno == EACCES)
76+
continue;
77+
fprintf(stderr, "Error getting active value for %s\n",
78+
names[i]);
79+
rc = -1;
80+
goto out;
81+
}
82+
pending = security_get_boolean_pending(names[i]);
83+
if (pending < 0) {
84+
fprintf(stderr, "Error getting pending value for %s\n",
85+
names[i]);
86+
rc = -1;
87+
goto out;
88+
}
89+
if (pending != active) {
90+
printf("%s --> %s pending: %s\n", names[i],
91+
(active ? "on" : "off"),
92+
(pending ? "on" : "off"));
93+
} else {
94+
printf("%s --> %s\n", names[i],
95+
(active ? "on" : "off"));
96+
}
97+
}
98+
99+
out:
100+
for (i = 0; i < len; i++)
101+
free(names[i]);
102+
free(names);
103+
return rc;
104+
}

toolbox/id.c

+13
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,10 @@
55
#include <pwd.h>
66
#include <grp.h>
77

8+
#ifdef HAVE_SELINUX
9+
#include <selinux/selinux.h>
10+
#endif
11+
812
static void print_uid(uid_t uid)
913
{
1014
struct passwd *pw = getpwuid(uid);
@@ -30,6 +34,9 @@ int id_main(int argc, char **argv)
3034
{
3135
gid_t list[64];
3236
int n, max;
37+
#ifdef HAVE_SELINUX
38+
char *secctx;
39+
#endif
3340

3441
max = getgroups(64, list);
3542
if (max < 0) max = 0;
@@ -46,6 +53,12 @@ int id_main(int argc, char **argv)
4653
print_gid(list[n]);
4754
}
4855
}
56+
#ifdef HAVE_SELINUX
57+
if (getcon(&secctx) == 0) {
58+
printf(" context=%s", secctx);
59+
free(secctx);
60+
}
61+
#endif
4962
printf("\n");
5063
return 0;
5164
}

toolbox/load_policy.c

+49
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
#include <stdio.h>
2+
#include <stdlib.h>
3+
#include <string.h>
4+
#include <unistd.h>
5+
#include <fcntl.h>
6+
#include <sys/stat.h>
7+
#include <sys/mman.h>
8+
#include <errno.h>
9+
#include <selinux/selinux.h>
10+
11+
int load_policy_main(int argc, char **argv)
12+
{
13+
int fd, rc, vers;
14+
struct stat sb;
15+
void *map;
16+
const char *path;
17+
18+
if (argc != 2) {
19+
fprintf(stderr, "usage: %s policy-file\n", argv[0]);
20+
exit(1);
21+
}
22+
23+
path = argv[1];
24+
fd = open(path, O_RDONLY);
25+
if (fd < 0) {
26+
fprintf(stderr, "Could not open %s: %s\n", path, strerror(errno));
27+
exit(2);
28+
}
29+
30+
if (fstat(fd, &sb) < 0) {
31+
fprintf(stderr, "Could not stat %s: %s\n", path, strerror(errno));
32+
exit(3);
33+
}
34+
35+
map = mmap(NULL, sb.st_size, PROT_READ, MAP_PRIVATE, fd, 0);
36+
if (map == MAP_FAILED) {
37+
fprintf(stderr, "Could not mmap %s: %s\n", path, strerror(errno));
38+
exit(4);
39+
}
40+
41+
rc = security_load_policy(map, sb.st_size);
42+
if (rc < 0) {
43+
fprintf(stderr, "Could not load %s: %s\n", path, strerror(errno));
44+
exit(5);
45+
}
46+
munmap(map, sb.st_size);
47+
close(fd);
48+
exit(0);
49+
}

toolbox/ls.c

+76-2
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,10 @@
55
#include <dirent.h>
66
#include <errno.h>
77

8+
#ifdef HAVE_SELINUX
9+
#include <selinux/selinux.h>
10+
#endif
11+
812
#include <sys/stat.h>
913
#include <unistd.h>
1014
#include <time.h>
@@ -25,6 +29,7 @@
2529
#define LIST_SIZE (1 << 4)
2630
#define LIST_LONG_NUMERIC (1 << 5)
2731
#define LIST_CLASSIFY (1 << 6)
32+
#define LIST_MACLABEL (1 << 7)
2833

2934
// fwd
3035
static int listpath(const char *name, int flags);
@@ -234,9 +239,75 @@ static int listfile_long(const char *path, int flags)
234239
return 0;
235240
}
236241

242+
static int listfile_maclabel(const char *path, int flags)
243+
{
244+
struct stat s;
245+
char mode[16];
246+
char user[16];
247+
char group[16];
248+
char *maclabel = NULL;
249+
const char *name;
250+
251+
/* name is anything after the final '/', or the whole path if none*/
252+
name = strrchr(path, '/');
253+
if(name == 0) {
254+
name = path;
255+
} else {
256+
name++;
257+
}
258+
259+
if(lstat(path, &s) < 0) {
260+
return -1;
261+
}
262+
263+
#ifdef HAVE_SELINUX
264+
lgetfilecon(path, &maclabel);
265+
#else
266+
maclabel = strdup("-");
267+
#endif
268+
if (!maclabel) {
269+
return -1;
270+
}
271+
272+
mode2str(s.st_mode, mode);
273+
user2str(s.st_uid, user);
274+
group2str(s.st_gid, group);
275+
276+
switch(s.st_mode & S_IFMT) {
277+
case S_IFLNK: {
278+
char linkto[256];
279+
int len;
280+
281+
len = readlink(path, linkto, sizeof(linkto));
282+
if(len < 0) return -1;
283+
284+
if(len > sizeof(linkto)-1) {
285+
linkto[sizeof(linkto)-4] = '.';
286+
linkto[sizeof(linkto)-3] = '.';
287+
linkto[sizeof(linkto)-2] = '.';
288+
linkto[sizeof(linkto)-1] = 0;
289+
} else {
290+
linkto[len] = 0;
291+
}
292+
293+
printf("%s %-8s %-8s %s %s -> %s\n",
294+
mode, user, group, maclabel, name, linkto);
295+
break;
296+
}
297+
default:
298+
printf("%s %-8s %-8s %s %s\n",
299+
mode, user, group, maclabel, name);
300+
301+
}
302+
303+
free(maclabel);
304+
305+
return 0;
306+
}
307+
237308
static int listfile(const char *dirname, const char *filename, int flags)
238309
{
239-
if ((flags & (LIST_LONG | LIST_SIZE | LIST_CLASSIFY)) == 0) {
310+
if ((flags & LIST_LONG | LIST_SIZE | LIST_CLASSIFY | LIST_MACLABEL) == 0) {
240311
printf("%s\n", filename);
241312
return 0;
242313
}
@@ -251,7 +322,9 @@ static int listfile(const char *dirname, const char *filename, int flags)
251322
pathname = filename;
252323
}
253324

254-
if ((flags & LIST_LONG) != 0) {
325+
if ((flags & LIST_MACLABEL) != 0) {
326+
return listfile_maclabel(pathname, flags);
327+
} else if ((flags & LIST_LONG) != 0) {
255328
return listfile_long(pathname, flags);
256329
} else /*((flags & LIST_SIZE) != 0)*/ {
257330
return listfile_size(pathname, filename, flags);
@@ -386,6 +459,7 @@ int ls_main(int argc, char **argv)
386459
case 's': flags |= LIST_SIZE; break;
387460
case 'R': flags |= LIST_RECURSIVE; break;
388461
case 'd': flags |= LIST_DIRECTORIES; break;
462+
case 'Z': flags |= LIST_MACLABEL; break;
389463
case 'a': flags |= LIST_ALL; break;
390464
case 'F': flags |= LIST_CLASSIFY; break;
391465
default:

0 commit comments

Comments
 (0)