Some callers of strtobool were passing a pointer to unterminated strings.
This fixes the issue and consolidates some logic in cifs.
Signed-off-by: Kees Cook
Cc: Amitkumar Karwar
Cc: Nishant Sarmukadam
Cc: Kalle Valo
Cc: Steve French
Cc: linux-c...@vger.kernel.org
---
This is preparation for adding "on"/"off" support to strtobool(), and I
want to make sure the solution isn't upsetting to the two callers. :)
---
drivers/net/wireless/marvell/mwifiex/debugfs.c | 6 +-
fs/cifs/cifs_debug.c | 78 --
fs/cifs/cifs_debug.h | 2 +-
fs/cifs/cifsfs.c | 6 +-
fs/cifs/cifsglob.h | 4 +-
5 files changed, 44 insertions(+), 52 deletions(-)
diff --git a/drivers/net/wireless/marvell/mwifiex/debugfs.c
b/drivers/net/wireless/marvell/mwifiex/debugfs.c
index 0b9c580af988..76af60899c69 100644
--- a/drivers/net/wireless/marvell/mwifiex/debugfs.c
+++ b/drivers/net/wireless/marvell/mwifiex/debugfs.c
@@ -880,13 +880,13 @@ mwifiex_reset_write(struct file *file,
{
struct mwifiex_private *priv = file->private_data;
struct mwifiex_adapter *adapter = priv->adapter;
- char cmd;
+ char cmd[2] = { '\0' };
bool result;
- if (copy_from_user(, ubuf, sizeof(cmd)))
+ if (copy_from_user(cmd, ubuf, sizeof(char)))
return -EFAULT;
- if (strtobool(, ))
+ if (strtobool(cmd, ))
return -EINVAL;
if (!result)
diff --git a/fs/cifs/cifs_debug.c b/fs/cifs/cifs_debug.c
index 50b268483302..cafe464fa1b7 100644
--- a/fs/cifs/cifs_debug.c
+++ b/fs/cifs/cifs_debug.c
@@ -251,11 +251,29 @@ static const struct file_operations
cifs_debug_data_proc_fops = {
.release= single_release,
};
+static int get_user_bool(const char __user *buffer, bool *store)
+{
+ char c[2] = { '\0' };
+ bool bv;
+ int rc;
+
+ rc = get_user(c[0], buffer);
+ if (rc)
+ return rc;
+
+ rc = strtobool(c, );
+ if (rc)
+ return rc;
+
+ *store = bv;
+
+ return 0;
+}
+
#ifdef CONFIG_CIFS_STATS
static ssize_t cifs_stats_proc_write(struct file *file,
const char __user *buffer, size_t count, loff_t *ppos)
{
- char c;
bool bv;
int rc;
struct list_head *tmp1, *tmp2, *tmp3;
@@ -263,11 +281,8 @@ static ssize_t cifs_stats_proc_write(struct file *file,
struct cifs_ses *ses;
struct cifs_tcon *tcon;
- rc = get_user(c, buffer);
- if (rc)
- return rc;
-
- if (strtobool(, ) == 0) {
+ rc = get_user_bool(buffer, );
+ if (rc == 0) {
#ifdef CONFIG_CIFS_STATS2
atomic_set(, 0);
atomic_set(, 0);
@@ -290,7 +305,8 @@ static ssize_t cifs_stats_proc_write(struct file *file,
}
}
spin_unlock(_tcp_ses_lock);
- }
+ } else
+ return rc;
return count;
}
@@ -433,17 +449,17 @@ static int cifsFYI_proc_open(struct inode *inode, struct
file *file)
static ssize_t cifsFYI_proc_write(struct file *file, const char __user *buffer,
size_t count, loff_t *ppos)
{
- char c;
+ char c[2] = { '\0' };
bool bv;
int rc;
- rc = get_user(c, buffer);
+ rc = get_user(c[0], buffer);
if (rc)
return rc;
- if (strtobool(, ) == 0)
+ if (strtobool(c, ) == 0)
cifsFYI = bv;
- else if ((c > '1') && (c <= '9'))
- cifsFYI = (int) (c - '0'); /* see cifs_debug.h for meanings */
+ else if ((c[0] > '1') && (c[0] <= '9'))
+ cifsFYI = (int) (c[0] - '0'); /* see cifs_debug.h for meanings
*/
return count;
}
@@ -471,20 +487,12 @@ static int cifs_linux_ext_proc_open(struct inode *inode,
struct file *file)
static ssize_t cifs_linux_ext_proc_write(struct file *file,
const char __user *buffer, size_t count, loff_t *ppos)
{
- char c;
- bool bv;
int rc;
- rc = get_user(c, buffer);
+ rc = get_user_bool(buffer, );
if (rc)
return rc;
- rc = strtobool(, );
- if (rc)
- return rc;
-
- linuxExtEnabled = bv;
-
return count;
}
@@ -511,20 +519,12 @@ static int cifs_lookup_cache_proc_open(struct inode
*inode, struct file *file)
static ssize_t cifs_lookup_cache_proc_write(struct file *file,
const char __user *buffer, size_t count, loff_t *ppos)
{
- char c;
- bool bv;
int rc;
- rc = get_user(c, buffer);
+ rc = get_user_bool(buffer, );
if (rc)
return rc;
- rc = strtobool(, );
- if (rc)
- return rc;
-
- lookupCacheEnabled