|
@@ -1356,6 +1356,10 @@ int search_binary_handler(struct linux_binprm *bprm)
|
|
struct linux_binfmt *fmt;
|
|
struct linux_binfmt *fmt;
|
|
pid_t old_pid, old_vpid;
|
|
pid_t old_pid, old_vpid;
|
|
|
|
|
|
|
|
+ /* This allows 4 levels of binfmt rewrites before failing hard. */
|
|
|
|
+ if (depth > 5)
|
|
|
|
+ return -ELOOP;
|
|
|
|
+
|
|
retval = security_bprm_check(bprm);
|
|
retval = security_bprm_check(bprm);
|
|
if (retval)
|
|
if (retval)
|
|
return retval;
|
|
return retval;
|
|
@@ -1380,12 +1384,8 @@ int search_binary_handler(struct linux_binprm *bprm)
|
|
if (!try_module_get(fmt->module))
|
|
if (!try_module_get(fmt->module))
|
|
continue;
|
|
continue;
|
|
read_unlock(&binfmt_lock);
|
|
read_unlock(&binfmt_lock);
|
|
|
|
+ bprm->recursion_depth = depth + 1;
|
|
retval = fn(bprm);
|
|
retval = fn(bprm);
|
|
- /*
|
|
|
|
- * Restore the depth counter to its starting value
|
|
|
|
- * in this call, so we don't have to rely on every
|
|
|
|
- * load_binary function to restore it on return.
|
|
|
|
- */
|
|
|
|
bprm->recursion_depth = depth;
|
|
bprm->recursion_depth = depth;
|
|
if (retval >= 0) {
|
|
if (retval >= 0) {
|
|
if (depth == 0) {
|
|
if (depth == 0) {
|