aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorOmar Sandoval <osandov@fb.com>2017-05-04 03:31:25 -0400
committerJens Axboe <axboe@fb.com>2017-05-04 10:23:16 -0400
commitc7e4145ae11b45931f117aa64c26be6cf58302df (patch)
treedd19aadf9aeca8a7ea558c8de30e9f02e21e8aff
parent1a435111f8eb30b370e3891caebb1d1ca61f41ec (diff)
blk-mq-debugfs: error on long write to queue "state" file
blk_queue_flags_store() currently truncates and returns a short write if the operation being written is too long. This can give us weird results, like here: $ echo "run bar" echo: write error: invalid argument $ dmesg [ 1103.075435] blk_queue_flags_store: unsupported operation bar. Use either 'run' or 'start' Instead, return an error if the user does this. While we're here, make the argument names consistent with everywhere else in this file. Signed-off-by: Omar Sandoval <osandov@fb.com> Reviewed-by: Hannes Reinecke <hare@suse.com> Signed-off-by: Jens Axboe <axboe@fb.com>
-rw-r--r--block/blk-mq-debugfs.c19
1 files changed, 12 insertions, 7 deletions
diff --git a/block/blk-mq-debugfs.c b/block/blk-mq-debugfs.c
index f58a116d6cca..2a19237455d4 100644
--- a/block/blk-mq-debugfs.c
+++ b/block/blk-mq-debugfs.c
@@ -107,14 +107,18 @@ static int blk_queue_flags_show(struct seq_file *m, void *v)
107 return 0; 107 return 0;
108} 108}
109 109
110static ssize_t blk_queue_flags_store(struct file *file, const char __user *ubuf, 110static ssize_t blk_queue_flags_store(struct file *file, const char __user *buf,
111 size_t len, loff_t *offp) 111 size_t count, loff_t *ppos)
112{ 112{
113 struct request_queue *q = file_inode(file)->i_private; 113 struct request_queue *q = file_inode(file)->i_private;
114 char op[16] = { }, *s; 114 char op[16] = { }, *s;
115 115
116 len = min(len, sizeof(op) - 1); 116 if (count >= sizeof(op)) {
117 if (copy_from_user(op, ubuf, len)) 117 pr_err("%s: operation too long\n", __func__);
118 goto inval;
119 }
120
121 if (copy_from_user(op, buf, count))
118 return -EFAULT; 122 return -EFAULT;
119 s = op; 123 s = op;
120 strsep(&s, " \t\n"); /* strip trailing whitespace */ 124 strsep(&s, " \t\n"); /* strip trailing whitespace */
@@ -123,11 +127,12 @@ static ssize_t blk_queue_flags_store(struct file *file, const char __user *ubuf,
123 } else if (strcmp(op, "start") == 0) { 127 } else if (strcmp(op, "start") == 0) {
124 blk_mq_start_stopped_hw_queues(q, true); 128 blk_mq_start_stopped_hw_queues(q, true);
125 } else { 129 } else {
126 pr_err("%s: unsupported operation %s. Use either 'run' or 'start'\n", 130 pr_err("%s: unsupported operation '%s'\n", __func__, op);
127 __func__, op); 131inval:
132 pr_err("%s: use either 'run' or 'start'\n", __func__);
128 return -EINVAL; 133 return -EINVAL;
129 } 134 }
130 return len; 135 return count;
131} 136}
132 137
133static int blk_queue_flags_open(struct inode *inode, struct file *file) 138static int blk_queue_flags_open(struct inode *inode, struct file *file)