Lines 1122-1131
typedef struct {
Link Here
|
1122 |
* |
1122 |
* |
1123 |
* XXX: Might be much nicer if we could serialize these vars behind the back of |
1123 |
* XXX: Might be much nicer if we could serialize these vars behind the back of |
1124 |
* the program. Might be hard to handle LD_PRELOAD though ... |
1124 |
* the program. Might be hard to handle LD_PRELOAD though ... |
|
|
1125 |
* |
1126 |
* execv*() must never modify environment inplace with |
1127 |
* setenv/putenv/unsetenv as it can relocate 'environ' and break |
1128 |
* vfork()/execv() users: https://bugs.gentoo.org/669702 |
1125 |
*/ |
1129 |
*/ |
1126 |
char **sb_check_envp(char **envp, size_t *mod_cnt, bool insert) |
1130 |
struct sb_envp_ctx sb_new_envp(char **envp, bool insert) |
1127 |
{ |
1131 |
{ |
1128 |
char **my_env; |
1132 |
struct sb_envp_ctx r = { |
|
|
1133 |
.sb_envp = envp, |
1134 |
.orig_envp = envp, |
1135 |
.__mod_cnt = 0, |
1136 |
}; |
1129 |
char *entry; |
1137 |
char *entry; |
1130 |
size_t count, i; |
1138 |
size_t count, i; |
1131 |
env_pair vars[] = { |
1139 |
env_pair vars[] = { |
Lines 1152-1158
char **sb_check_envp(char **envp, size_t *mod_cnt, bool insert)
Link Here
|
1152 |
/* If sandbox is explicitly disabled, do not propagate the vars |
1160 |
/* If sandbox is explicitly disabled, do not propagate the vars |
1153 |
* and just return user's envp */ |
1161 |
* and just return user's envp */ |
1154 |
if (!sbcontext.on) |
1162 |
if (!sbcontext.on) |
1155 |
return envp; |
1163 |
return r; |
1156 |
|
1164 |
|
1157 |
/* First figure out how many vars are already in the env */ |
1165 |
/* First figure out how many vars are already in the env */ |
1158 |
found_var_cnt = 0; |
1166 |
found_var_cnt = 0; |
Lines 1188-1194
char **sb_check_envp(char **envp, size_t *mod_cnt, bool insert)
Link Here
|
1188 |
if ((insert && num_vars == found_var_cnt) || |
1196 |
if ((insert && num_vars == found_var_cnt) || |
1189 |
(!insert && found_var_cnt == 0)) |
1197 |
(!insert && found_var_cnt == 0)) |
1190 |
/* Use the user's envp */ |
1198 |
/* Use the user's envp */ |
1191 |
return envp; |
1199 |
return r; |
1192 |
|
1200 |
|
1193 |
/* Ok, we need to create our own envp, as we need to restore stuff |
1201 |
/* Ok, we need to create our own envp, as we need to restore stuff |
1194 |
* and we should not touch the user's envp. First we add our vars, |
1202 |
* and we should not touch the user's envp. First we add our vars, |
Lines 1208-1268
char **sb_check_envp(char **envp, size_t *mod_cnt, bool insert)
Link Here
|
1208 |
vars[13].value = "1"; |
1216 |
vars[13].value = "1"; |
1209 |
} |
1217 |
} |
1210 |
|
1218 |
|
1211 |
my_env = NULL; |
1219 |
char ** my_env = NULL; |
1212 |
if (!insert) { |
1220 |
if (!insert) { |
1213 |
if (mod_cnt) { |
1221 |
str_list_for_each_item(envp, entry, count) { |
1214 |
str_list_for_each_item(envp, entry, count) { |
|
|
1215 |
for (i = 0; i < num_vars; ++i) |
1216 |
if (i != 12 && is_env_var(entry, vars[i].name, vars[i].len)) { |
1217 |
(*mod_cnt)++; |
1218 |
goto skip; |
1219 |
} |
1220 |
str_list_add_item(my_env, entry, error); |
1221 |
skip: ; |
1222 |
} |
1223 |
} else { |
1224 |
for (i = 0; i < num_vars; ++i) |
1222 |
for (i = 0; i < num_vars; ++i) |
1225 |
if (i != 12) unsetenv(vars[i].name); |
1223 |
if (i != 12 /* LD_LIBRARY_PATH index */ |
|
|
1224 |
&& is_env_var(entry, vars[i].name, vars[i].len)) { |
1225 |
r.__mod_cnt++; |
1226 |
goto skip; |
1227 |
} |
1228 |
str_list_add_item(my_env, entry, error); |
1229 |
skip: ; |
1226 |
} |
1230 |
} |
1227 |
} else { |
1231 |
} else { |
1228 |
if (mod_cnt) { |
1232 |
/* Count directly due to variability with LD_PRELOAD and the value |
1229 |
/* Count directly due to variability with LD_PRELOAD and the value |
1233 |
* logic below. Getting out of sync can mean memory corruption. */ |
1230 |
* logic below. Getting out of sync can mean memory corruption. */ |
1234 |
r.__mod_cnt = 0; |
1231 |
*mod_cnt = 0; |
1235 |
if (unlikely(merge_ld_preload)) { |
1232 |
if (unlikely(merge_ld_preload)) { |
1236 |
str_list_add_item(my_env, ld_preload, error); |
1233 |
str_list_add_item(my_env, ld_preload, error); |
1237 |
r.__mod_cnt++; |
1234 |
(*mod_cnt)++; |
1238 |
} |
1235 |
} |
1239 |
for (i = 0; i < num_vars; ++i) { |
1236 |
for (i = 0; i < num_vars; ++i) { |
1240 |
if (found_vars[i] || !vars[i].value) |
1237 |
if (found_vars[i] || !vars[i].value) |
1241 |
continue; |
1238 |
continue; |
1242 |
str_list_add_item_env(my_env, vars[i].name, vars[i].value, error); |
1239 |
str_list_add_item_env(my_env, vars[i].name, vars[i].value, error); |
1243 |
r.__mod_cnt++; |
1240 |
(*mod_cnt)++; |
1244 |
} |
1241 |
} |
|
|
1242 |
|
1245 |
|
1243 |
str_list_for_each_item(envp, entry, count) { |
1246 |
str_list_for_each_item(envp, entry, count) { |
1244 |
if (unlikely(merge_ld_preload && is_env_var(entry, vars[0].name, vars[0].len))) |
1247 |
if (unlikely(merge_ld_preload && is_env_var(entry, vars[0].name, vars[0].len))) |
1245 |
continue; |
1248 |
continue; |
1246 |
str_list_add_item(my_env, entry, error); |
1249 |
str_list_add_item(my_env, entry, error); |
1247 |
} |
|
|
1248 |
} else { |
1249 |
if (unlikely(merge_ld_preload)) |
1250 |
putenv(ld_preload); |
1251 |
for (i = 0; i < num_vars; ++i) { |
1252 |
if (found_vars[i] || !vars[i].value) |
1253 |
continue; |
1254 |
setenv(vars[i].name, vars[i].value, 1); |
1255 |
} |
1256 |
} |
1250 |
} |
1257 |
} |
1251 |
} |
1258 |
|
1252 |
|
1259 |
error: |
1253 |
error: |
1260 |
return my_env; |
1254 |
r.sb_envp = my_env; |
|
|
1255 |
return r; |
1261 |
} |
1256 |
} |
1262 |
|
1257 |
|
1263 |
void sb_cleanup_envp(char **envp, size_t mod_cnt) |
1258 |
void sb_free_envp(struct sb_envp_ctx * envp_ctx) |
1264 |
{ |
1259 |
{ |
1265 |
/* We assume all the stuffed vars are at the start */ |
1260 |
/* We assume all the stuffed vars are at the start */ |
|
|
1261 |
size_t mod_cnt = envp_ctx->__mod_cnt; |
1262 |
char ** envp = envp_ctx->sb_envp; |
1266 |
size_t i; |
1263 |
size_t i; |
1267 |
for (i = 0; i < mod_cnt; ++i) |
1264 |
for (i = 0; i < mod_cnt; ++i) |
1268 |
free(envp[i]); |
1265 |
free(envp[i]); |
Lines 1271-1275
void sb_cleanup_envp(char **envp, size_t mod_cnt)
Link Here
|
1271 |
* entries except for LD_PRELOAD. All the other entries are |
1268 |
* entries except for LD_PRELOAD. All the other entries are |
1272 |
* pointers to existing envp memory. |
1269 |
* pointers to existing envp memory. |
1273 |
*/ |
1270 |
*/ |
1274 |
free(envp); |
1271 |
if (envp != envp_ctx->orig_envp) |
|
|
1272 |
free(envp); |
1275 |
} |
1273 |
} |