summaryrefslogtreecommitdiff
path: root/fs
diff options
context:
space:
mode:
Diffstat (limited to 'fs')
-rw-r--r--fs/binfmt_misc_bpf.c20
1 files changed, 18 insertions, 2 deletions
diff --git a/fs/binfmt_misc_bpf.c b/fs/binfmt_misc_bpf.c
index ce1bc78e8511..a3e26e8a4027 100644
--- a/fs/binfmt_misc_bpf.c
+++ b/fs/binfmt_misc_bpf.c
@@ -141,8 +141,6 @@ __bpf_kfunc int bpf_binprm_set_interp(struct linux_binprm *bprm,
len = strnlen(path, path__sz);
if (len == path__sz)
return -EINVAL;
- if (path[0] != '/')
- return -EINVAL;
if (len >= PATH_MAX)
return -ENAMETOOLONG;
@@ -150,6 +148,15 @@ __bpf_kfunc int bpf_binprm_set_interp(struct linux_binprm *bprm,
if (!interp)
return -ENOMEM;
+ /*
+ * The program may pass memory that is written to while this runs,
+ * so check the private copy and not the buffer it was made from.
+ */
+ if (interp[0] != '/') {
+ kfree(interp);
+ return -EINVAL;
+ }
+
bm_bpf_stage_selection(bprm, interp, NULL);
return 0;
}
@@ -241,6 +248,15 @@ __bpf_kfunc int bpf_binprm_set_interp_arg(struct linux_binprm *bprm,
if (!val)
return -ENOMEM;
+ /*
+ * The program may pass memory that is written to while this runs,
+ * so check the private copy and not the buffer it was made from.
+ */
+ if (!val[0]) {
+ kfree(val);
+ return -EINVAL;
+ }
+
kfree(bprm->bpf_interp_arg);
bprm->bpf_interp_arg = val;
return 0;