sysctl: Make sure proc handlers can't expose heap memory
Subsystems (4)
PATCH 1/1 sysctl: Make sure proc handlers can't expose heap memory
Just as a precaution, make sure that proc handlers don't accidentally grow "count" beyond the allocated kbuf size.
---
This applies to hch's sysctl cleanup tree...
--- fs/proc/proc_sysctl.c | 3 +++ 1 file changed, 3 insertions(+)
fs/proc/proc_sysctl.c +3 -0
@@ -546,6 +546,7 @@ static ssize_t proc_sys_call_handler(struct file *filp, void __user *ubuf,struct inode *inode =file_inode (filp);struct ctl_table_header *head =grab_header (inode);struct ctl_table *table =PROC_I (inode)->sysctl_entry; +size_t count_max = count;void *kbuf;ssize_t error;
@@ -590,6 +591,8 @@ static ssize_t proc_sys_call_handler(struct file *filp, void __user *ubuf,if (!write) { error = -EFAULT ; +if (WARN_ON (count > count_max)) + count = count_max;if (copy_to_user (ubuf, kbuf, count)) goto out_free_buf; }
Signature · 5 lines
2.20.1 -- Kees Cook
Quoted 23 lines · Kees Cook
Just as a precaution, make sure that proc handlers don't accidentally grow "count" beyond the allocated kbuf size.
Signed-off-by Kees Cook <[email protected]>---
This applies to hch's sysctl cleanup tree...--- fs/proc/proc_sysctl.c | 3 +++ 1 file changed, 3 insertions(+)fs/proc/proc_sysctl.c +1
-0@@ -546,6 +546,7 @@ static ssize_t proc_sys_call_handler(struct file *filp, void __user *ubuf,struct inode *inode =file_inode (filp);struct ctl_table_header *head =grab_header (inode);struct ctl_table *table =PROC_I (inode)->sysctl_entry; +size_t count_max = count;void *kbuf;ssize_t error;
fs/proc/proc_sysctl.c static ssize_t proc_sys_call_handler(struct file *filp, void __user *ubuf, · line 595
Quoted 5 lines
fs/proc/proc_sysctl.c +2
-0@@ -590,6 +591,8 @@ static ssize_t proc_sys_call_handler(struct file *filp, void __user *ubuf,if (!write) { error = -EFAULT ; +if (WARN_ON (count > count_max)) + count = count_max;
That crash a system with panic-on-warn. I don't think we want that?
Luis
Quoted 23 lines · Luis Chamberlain
Quoted 22 lines · Kees Cook
Just as a precaution, make sure that proc handlers don't accidentally grow "count" beyond the allocated kbuf size.
Signed-off-by Kees Cook <[email protected]>---
This applies to hch's sysctl cleanup tree...--- fs/proc/proc_sysctl.c | 3 +++ 1 file changed, 3 insertions(+)fs/proc/proc_sysctl.c +1
-0@@ -546,6 +546,7 @@ static ssize_t proc_sys_call_handler(struct file *filp, void __user *ubuf,struct inode *inode =file_inode (filp);struct ctl_table_header *head =grab_header (inode);struct ctl_table *table =PROC_I (inode)->sysctl_entry; +size_t count_max = count;void *kbuf;ssize_t error;
Quoted 8 lines
fs/proc/proc_sysctl.c static ssize_t proc_sys_call_handler(struct file *filp, void __user *ubuf, · line 595
Quoted 6 lines
fs/proc/proc_sysctl.c +2
-0@@ -590,6 +591,8 @@ static ssize_t proc_sys_call_handler(struct file *filp, void __user *ubuf,if (!write) { error = -EFAULT ; +if (WARN_ON (count > count_max)) + count = count_max;That crash a system with panic-on-warn. I don't think we want that?
Eh? None of the handlers should be making this mistake currently and it's not a mistake that can be controlled from userspace. WARN() is absolutely what's wanted here: report an impossible situation (and handle it gracefully for the bulk of users that don't have panic_on_warn set).
Signature · 1 line
Kees Cook
Quoted 33 lines · Kees Cook
Quoted 23 lines · Luis Chamberlain
Quoted 22 lines · Kees Cook
Just as a precaution, make sure that proc handlers don't accidentally grow "count" beyond the allocated kbuf size.
Signed-off-by Kees Cook <[email protected]>---
This applies to hch's sysctl cleanup tree...--- fs/proc/proc_sysctl.c | 3 +++ 1 file changed, 3 insertions(+)fs/proc/proc_sysctl.c +1
-0@@ -546,6 +546,7 @@ static ssize_t proc_sys_call_handler(struct file *filp, void __user *ubuf,struct inode *inode =file_inode (filp);struct ctl_table_header *head =grab_header (inode);struct ctl_table *table =PROC_I (inode)->sysctl_entry; +size_t count_max = count;void *kbuf;ssize_t error;Quoted 8 lines
fs/proc/proc_sysctl.c static ssize_t proc_sys_call_handler(struct file *filp, void __user *ubuf, · line 595
Quoted 6 lines
fs/proc/proc_sysctl.c +2
-0@@ -590,6 +591,8 @@ static ssize_t proc_sys_call_handler(struct file *filp, void __user *ubuf,if (!write) { error = -EFAULT ; +if (WARN_ON (count > count_max)) + count = count_max;That would crash a system with panic-on-warn. I don't think we want that?
Quoted 5 lines
Eh? None of the handlers should be making this mistake currently and it's not a mistake that can be controlled from userspace.
WARN()is absolutely what's wanted here: report an impossible situation (and handle it gracefully for the bulk of users that don't havepanic_on_warnset).
Alrighty, Greg are you OK with this type of WARN_ON()? You recently expressed concerns over its use due to panic-on-warn on another patch.
LUis
Quoted 6 lines · Kees Cook
Just as a precaution, make sure that proc handlers don't accidentally grow "count" beyond the allocated kbuf size.
Signed-off-by Kees Cook <[email protected]>---
This applies to hch's sysctl cleanup tree...
This looks ok o me. You should probably add Al to the Cc list as he has picked up my series into a branch of vfs.git.
Quoted 34 lines · Luis Chamberlain
Quoted 33 lines · Kees Cook
Quoted 31 lines · Luis Chamberlain
Quoted 23 lines · Kees Cook
Just as a precaution, make sure that proc handlers don't accidentally grow "count" beyond the allocated kbuf size.
Signed-off-by Kees Cook <[email protected]>---
This applies to hch's sysctl cleanup tree...--- fs/proc/proc_sysctl.c | 3 +++ 1 file changed, 3 insertions(+)fs/proc/proc_sysctl.c +1
-0@@ -546,6 +546,7 @@ static ssize_t proc_sys_call_handler(struct file *filp, void __user *ubuf,struct inode *inode =file_inode (filp);struct ctl_table_header *head =grab_header (inode);struct ctl_table *table =PROC_I (inode)->sysctl_entry; +size_t count_max = count;void *kbuf;ssize_t error;fs/proc/proc_sysctl.c static ssize_t proc_sys_call_handler(struct file *filp, void __user *ubuf, · line 595
Quoted 5 lines
fs/proc/proc_sysctl.c +2
-0@@ -590,6 +591,8 @@ static ssize_t proc_sys_call_handler(struct file *filp, void __user *ubuf,if (!write) { error = -EFAULT ; +if (WARN_ON (count > count_max)) + count = count_max;That would crash a system with panic-on-warn. I don't think we want that?
Quoted 8 lines
Quoted 5 lines
Eh? None of the handlers should be making this mistake currently and it's not a mistake that can be controlled from userspace.
WARN()is absolutely what's wanted here: report an impossible situation (and handle it gracefully for the bulk of users that don't havepanic_on_warnset).Alrighty, Greg are you OK with this type of
WARN_ON()? You recently expressed concerns over its use due to panic-on-warn on another patch.
We should never call WARN() on any path that a user can trigger.
If it is just a "the developer called this api in a foolish way" then we could use a WARN_ON() to have them realize their mistake, but in my personal experience, foolish developers don't even notice that kind of mistake :(
thanks,
greg k-h
Quoted 44 lines · Greg KH
Quoted 34 lines · Luis Chamberlain
Quoted 33 lines · Kees Cook
Quoted 31 lines · Luis Chamberlain
Quoted 23 lines · Kees Cook
Just as a precaution, make sure that proc handlers don't accidentally grow "count" beyond the allocated kbuf size.
Signed-off-by Kees Cook <[email protected]>---
This applies to hch's sysctl cleanup tree...--- fs/proc/proc_sysctl.c | 3 +++ 1 file changed, 3 insertions(+)fs/proc/proc_sysctl.c +1
-0@@ -546,6 +546,7 @@ static ssize_t proc_sys_call_handler(struct file *filp, void __user *ubuf,struct inode *inode =file_inode (filp);struct ctl_table_header *head =grab_header (inode);struct ctl_table *table =PROC_I (inode)->sysctl_entry; +size_t count_max = count;void *kbuf;ssize_t error;fs/proc/proc_sysctl.c static ssize_t proc_sys_call_handler(struct file *filp, void __user *ubuf, · line 595
Quoted 5 lines
fs/proc/proc_sysctl.c +2
-0@@ -590,6 +591,8 @@ static ssize_t proc_sys_call_handler(struct file *filp, void __user *ubuf,if (!write) { error = -EFAULT ; +if (WARN_ON (count > count_max)) + count = count_max;That would crash a system with panic-on-warn. I don't think we want that?
Quoted 8 lines
Quoted 5 lines
Eh? None of the handlers should be making this mistake currently and it's not a mistake that can be controlled from userspace.
WARN()is absolutely what's wanted here: report an impossible situation (and handle it gracefully for the bulk of users that don't havepanic_on_warnset).Alrighty, Greg are you OK with this type of
WARN_ON()? You recently expressed concerns over its use due to panic-on-warn on another patch.
Quoted 6 lines
We should never call
WARN()on any path that a user can trigger.If it is just a "the developer called this api in a foolish way" then we could use a
WARN_ON()to have them realize their mistake, but in my personal experience, foolish developers don't even notice that kind of mistake :(
Right -- while it'd be nice if the developer noticed it, it is _usually_ an unsuspecting end user (or fuzzer), in which case we absolutely want a WARN (and not a BUG![1]) and have the situations handled gracefully, so it can be reported and fixed.
-Kees
[1] https://www.kernel.org/doc/html/latest/process/deprecated.html#bug-and-bug-on
Signature · 1 line
Kees Cook
Quoted 52 lines · Kees Cook
Quoted 44 lines · Greg KH
Quoted 34 lines · Luis Chamberlain
Quoted 33 lines · Kees Cook
Quoted 31 lines · Luis Chamberlain
Quoted 23 lines · Kees Cook
Just as a precaution, make sure that proc handlers don't accidentally grow "count" beyond the allocated kbuf size.
Signed-off-by Kees Cook <[email protected]>---
This applies to hch's sysctl cleanup tree...--- fs/proc/proc_sysctl.c | 3 +++ 1 file changed, 3 insertions(+)fs/proc/proc_sysctl.c +1
-0@@ -546,6 +546,7 @@ static ssize_t proc_sys_call_handler(struct file *filp, void __user *ubuf,struct inode *inode =file_inode (filp);struct ctl_table_header *head =grab_header (inode);struct ctl_table *table =PROC_I (inode)->sysctl_entry; +size_t count_max = count;void *kbuf;ssize_t error;fs/proc/proc_sysctl.c static ssize_t proc_sys_call_handler(struct file *filp, void __user *ubuf, · line 595
Quoted 5 lines
fs/proc/proc_sysctl.c +2
-0@@ -590,6 +591,8 @@ static ssize_t proc_sys_call_handler(struct file *filp, void __user *ubuf,if (!write) { error = -EFAULT ; +if (WARN_ON (count > count_max)) + count = count_max;That would crash a system with panic-on-warn. I don't think we want that?
Quoted 8 lines
Quoted 5 lines
Eh? None of the handlers should be making this mistake currently and it's not a mistake that can be controlled from userspace.
WARN()is absolutely what's wanted here: report an impossible situation (and handle it gracefully for the bulk of users that don't havepanic_on_warnset).Alrighty, Greg are you OK with this type of
WARN_ON()? You recently expressed concerns over its use due to panic-on-warn on another patch.Quoted 6 lines
We should never call
WARN()on any path that a user can trigger.If it is just a "the developer called this api in a foolish way" then we could use a
WARN_ON()to have them realize their mistake, but in my personal experience, foolish developers don't even notice that kind of mistake :(
Quoted 4 lines
Right -- while it'd be nice if the developer noticed it, it is _usually_ an unsuspecting end user (or fuzzer), in which case we absolutely want a WARN (and not a BUG![1]) and have the situations handled gracefully, so it can be reported and fixed.
I've been using WARN*() for this exact purpose before, so I am as surprised as you are bout these concerns. However if we have folks shipping with panic-on-warn this would be rather detrimental to our goals.
Greg, are you aware of folks shipping with panic-on-warn on some products?
Luis
Quoted 8 lines · Luis Chamberlain
Quoted 4 lines · Kees Cook
Right -- while it'd be nice if the developer noticed it, it is _usually_ an unsuspecting end user (or fuzzer), in which case we absolutely want a WARN (and not a BUG![1]) and have the situations handled gracefully, so it can be reported and fixed.
I've been using WARN*() for this exact purpose before, so I am as surprised as you are bout these concerns. However if we have folks
I don't see any mismatch here: it's not user-reachable, which is what Greg said. WARN is for non-user-reachable "impossible situations". We want to know if those can be hit (via bad API usage, races, etc). If it's reachable from userspace, then it can't be a WARN() any more and needs to be pr_warn().
Quoted 4 lines
shipping with panic-on-warn this would be rather detrimental to our goals.
Greg, are you aware of folks shipping with panic-on-warn on some products?
People shipping with panic_on_warn are expecting to panic for WARNs like this. :P
Signature · 1 line
Kees Cook