diff options
-rw-r--r-- | fs/pstore/platform.c | 46 |
1 files changed, 20 insertions, 26 deletions
diff --git a/fs/pstore/platform.c b/fs/pstore/platform.c index e79f170fa79b..43b3ca5e045f 100644 --- a/fs/pstore/platform.c +++ b/fs/pstore/platform.c | |||
@@ -635,33 +635,27 @@ static void pstore_unregister_console(void) {} | |||
635 | static int pstore_write_user_compat(struct pstore_record *record, | 635 | static int pstore_write_user_compat(struct pstore_record *record, |
636 | const char __user *buf) | 636 | const char __user *buf) |
637 | { | 637 | { |
638 | unsigned long flags = 0; | 638 | int ret = 0; |
639 | size_t i, bufsize, total_size = record->size; | 639 | |
640 | long ret = 0; | 640 | if (record->buf) |
641 | 641 | return -EINVAL; | |
642 | if (unlikely(!access_ok(VERIFY_READ, buf, total_size))) | 642 | |
643 | return -EFAULT; | 643 | record->buf = kmalloc(record->size, GFP_KERNEL); |
644 | bufsize = total_size; | 644 | if (!record->buf) |
645 | if (bufsize > psinfo->bufsize) | 645 | return -ENOMEM; |
646 | bufsize = psinfo->bufsize; | 646 | |
647 | record->buf = psinfo->buf; | 647 | if (unlikely(copy_from_user(record->buf, buf, record->size))) { |
648 | spin_lock_irqsave(&psinfo->buf_lock, flags); | 648 | ret = -EFAULT; |
649 | for (i = 0; i < total_size; ) { | 649 | goto out; |
650 | size_t c = min(total_size - i, bufsize); | ||
651 | |||
652 | ret = __copy_from_user(record->buf, buf + i, c); | ||
653 | if (unlikely(ret != 0)) { | ||
654 | ret = -EFAULT; | ||
655 | break; | ||
656 | } | ||
657 | record->size = c; | ||
658 | ret = record->psi->write(record); | ||
659 | if (unlikely(ret < 0)) | ||
660 | break; | ||
661 | i += c; | ||
662 | } | 650 | } |
663 | spin_unlock_irqrestore(&psinfo->buf_lock, flags); | 651 | |
664 | return unlikely(ret < 0) ? ret : total_size; | 652 | ret = record->psi->write(record); |
653 | |||
654 | out: | ||
655 | kfree(record->buf); | ||
656 | record->buf = NULL; | ||
657 | |||
658 | return unlikely(ret < 0) ? ret : record->size; | ||
665 | } | 659 | } |
666 | 660 | ||
667 | /* | 661 | /* |