Skip to content

Commit 538413f

Browse files
committed
CM specific changes to allow disabling of root access from system settings
1 parent 8bf97db commit 538413f

File tree

5 files changed

+181
-5
lines changed

5 files changed

+181
-5
lines changed

Android.mk

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ LOCAL_PATH := $(call my-dir)
22
include $(CLEAR_VARS)
33

44
LOCAL_MODULE := su
5-
LOCAL_SRC_FILES := su.c db.c activity.c
5+
LOCAL_SRC_FILES := su.c db.c activity.c utils.c
66

77
LOCAL_C_INCLUDES += external/sqlite/dist
88

su.c

Lines changed: 51 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@
3838
#include <cutils/log.h>
3939

4040
#include "su.h"
41+
#include "utils.h"
4142

4243
/* Still lazt, will fix this */
4344
static char socket_path[PATH_MAX];
@@ -375,8 +376,10 @@ int main(int argc, char *argv[])
375376
};
376377
struct stat st;
377378
int socket_serv_fd, fd;
378-
char buf[64], *result;
379-
int c, dballow;
379+
char buf[64], *result, debuggable[PROPERTY_VALUE_MAX];
380+
char enabled[PROPERTY_VALUE_MAX], build_type[PROPERTY_VALUE_MAX];
381+
char cm_version[PROPERTY_VALUE_MAX];;
382+
int c, dballow, len;
380383
struct option long_opts[] = {
381384
{ "command", required_argument, NULL, 'c' },
382385
{ "help", no_argument, NULL, 'h' },
@@ -386,6 +389,8 @@ int main(int argc, char *argv[])
386389
{ "version", no_argument, NULL, 'v' },
387390
{ NULL, 0, NULL, 0 },
388391
};
392+
char *data;
393+
unsigned sz;
389394

390395
while ((c = getopt_long(argc, argv, "+c:hlmps:Vv", long_opts, NULL)) != -1) {
391396
switch(c) {
@@ -450,8 +455,52 @@ int main(int argc, char *argv[])
450455
deny(&ctx);
451456
}
452457

458+
// we can't simply use the property service, since we aren't launched from init and
459+
// can't trust the location of the property workspace. find the properties ourselves.
460+
data = read_file("/default.prop", &sz);
461+
get_property(data, debuggable, "ro.debuggable", "0");
462+
free(data);
463+
464+
data = read_file("/system/build.prop", &sz);
465+
get_property(data, cm_version, "ro.cm.version", "");
466+
get_property(data, build_type, "ro.build.type", "");
467+
free(data);
468+
469+
data = read_file("/data/property/persist.sys.root_access", &sz);
470+
if (data != NULL) {
471+
len = strlen(data);
472+
if (len >= PROPERTY_VALUE_MAX)
473+
memcpy(enabled, "1", 2);
474+
else
475+
memcpy(enabled, data, len + 1);
476+
free(data);
477+
} else
478+
memcpy(enabled, "1", 2);
479+
453480
ctx.umask = umask(027);
454481

482+
// CyanogenMod-specific behavior
483+
if (strlen(cm_version) > 0) {
484+
// only allow su on debuggable builds
485+
if (strcmp("1", debuggable) != 0) {
486+
LOGE("Root access is disabled on non-debug builds");
487+
deny(&ctx);
488+
}
489+
490+
// enforce persist.sys.root_access on non-eng builds
491+
if (strcmp("eng", build_type) != 0 &&
492+
(atoi(enabled) & 1) != 1 ) {
493+
LOGE("Root access is disabled by system setting - enable it under settings -> developer options");
494+
deny(&ctx);
495+
}
496+
497+
// disallow su in a shell if appropriate
498+
if (ctx.from.uid == AID_SHELL && (atoi(enabled) == 1)) {
499+
LOGE("Root access is disabled by a system setting - enable it under settings -> developer options");
500+
deny(&ctx);
501+
}
502+
}
503+
455504
if (ctx.from.uid == AID_ROOT || ctx.from.uid == AID_SHELL)
456505
allow(&ctx);
457506

su.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -42,8 +42,8 @@
4242
#define VERSION_EXTRA ""
4343
#endif
4444

45-
#define VERSION "3.1" VERSION_EXTRA
46-
#define VERSION_CODE 16
45+
#define VERSION "3.1.1" VERSION_EXTRA
46+
#define VERSION_CODE 17
4747

4848
#define DATABASE_VERSION 6
4949
#define PROTO_VERSION 0

utils.c

Lines changed: 103 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,103 @@
1+
/*
2+
** Copyright 2012, The CyanogenMod Project
3+
**
4+
** Licensed under the Apache License, Version 2.0 (the "License");
5+
** you may not use this file except in compliance with the License.
6+
** You may obtain a copy of the License at
7+
**
8+
** http://www.apache.org/licenses/LICENSE-2.0
9+
**
10+
** Unless required by applicable law or agreed to in writing, software
11+
** distributed under the License is distributed on an "AS IS" BASIS,
12+
** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
** See the License for the specific language governing permissions and
14+
** limitations under the License.
15+
*/
16+
17+
#include <unistd.h>
18+
#include <limits.h>
19+
#include <fcntl.h>
20+
#include <errno.h>
21+
#include <endian.h>
22+
#include <ctype.h>
23+
24+
#include <stdio.h>
25+
#include <stdlib.h>
26+
#include <string.h>
27+
#include <cutils/properties.h>
28+
29+
/* reads a file, making sure it is terminated with \n \0 */
30+
char* read_file(const char *fn, unsigned *_sz)
31+
{
32+
char *data;
33+
int sz;
34+
int fd;
35+
36+
data = 0;
37+
fd = open(fn, O_RDONLY);
38+
if(fd < 0) return 0;
39+
40+
sz = lseek(fd, 0, SEEK_END);
41+
if(sz < 0) goto oops;
42+
43+
if(lseek(fd, 0, SEEK_SET) != 0) goto oops;
44+
45+
data = (char*) malloc(sz + 2);
46+
if(data == 0) goto oops;
47+
48+
if(read(fd, data, sz) != sz) goto oops;
49+
close(fd);
50+
data[sz] = '\n';
51+
data[sz+1] = 0;
52+
if(_sz) *_sz = sz;
53+
return data;
54+
55+
oops:
56+
close(fd);
57+
if(data != 0) free(data);
58+
return 0;
59+
}
60+
61+
int get_property(const char *data, char *found, const char *searchkey, const char *not_found)
62+
{
63+
char *key, *value, *eol, *sol, *tmp;
64+
if (data == NULL) goto defval;
65+
int matched = 0;
66+
sol = strdup(data);
67+
while((eol = strchr(sol, '\n'))) {
68+
key = sol;
69+
*eol++ = 0;
70+
sol = eol;
71+
72+
value = strchr(key, '=');
73+
if(value == 0) continue;
74+
*value++ = 0;
75+
76+
while(isspace(*key)) key++;
77+
if(*key == '#') continue;
78+
tmp = value - 2;
79+
while((tmp > key) && isspace(*tmp)) *tmp-- = 0;
80+
81+
while(isspace(*value)) value++;
82+
tmp = eol - 2;
83+
while((tmp > value) && isspace(*tmp)) *tmp-- = 0;
84+
85+
if (strncmp(searchkey, key, strlen(searchkey)) == 0) {
86+
matched = 1;
87+
break;
88+
}
89+
}
90+
int len;
91+
if (matched) {
92+
len = strlen(value);
93+
if (len >= PROPERTY_VALUE_MAX)
94+
return -1;
95+
memcpy(found, value, len + 1);
96+
} else goto defval;
97+
return len;
98+
99+
defval:
100+
len = strlen(not_found);
101+
memcpy(found, not_found, len + 1);
102+
return len;
103+
}

utils.h

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
/*
2+
** Copyright 2012, The CyanogenMod Project
3+
**
4+
** Licensed under the Apache License, Version 2.0 (the "License");
5+
** you may not use this file except in compliance with the License.
6+
** You may obtain a copy of the License at
7+
**
8+
** http://www.apache.org/licenses/LICENSE-2.0
9+
**
10+
** Unless required by applicable law or agreed to in writing, software
11+
** distributed under the License is distributed on an "AS IS" BASIS,
12+
** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
** See the License for the specific language governing permissions and
14+
** limitations under the License.
15+
*/
16+
17+
#ifndef _UTILS_H_
18+
#define _UTILS_H_
19+
20+
/* reads a file, making sure it is terminated with \n \0 */
21+
char* read_file(const char *fn, unsigned *_sz);
22+
23+
int get_property(const char *data, char *found, const char *searchkey, const char *not_found);
24+
#endif

0 commit comments

Comments
 (0)