diff options
Diffstat (limited to 'fs/proc/base.c')
-rw-r--r-- | fs/proc/base.c | 14 |
1 files changed, 13 insertions, 1 deletions
diff --git a/fs/proc/base.c b/fs/proc/base.c index be1909041685..d9512bd03e6c 100644 --- a/fs/proc/base.c +++ b/fs/proc/base.c | |||
@@ -711,6 +711,13 @@ static int mem_open(struct inode* inode, struct file* file) | |||
711 | if (IS_ERR(mm)) | 711 | if (IS_ERR(mm)) |
712 | return PTR_ERR(mm); | 712 | return PTR_ERR(mm); |
713 | 713 | ||
714 | if (mm) { | ||
715 | /* ensure this mm_struct can't be freed */ | ||
716 | atomic_inc(&mm->mm_count); | ||
717 | /* but do not pin its memory */ | ||
718 | mmput(mm); | ||
719 | } | ||
720 | |||
714 | /* OK to pass negative loff_t, we can catch out-of-range */ | 721 | /* OK to pass negative loff_t, we can catch out-of-range */ |
715 | file->f_mode |= FMODE_UNSIGNED_OFFSET; | 722 | file->f_mode |= FMODE_UNSIGNED_OFFSET; |
716 | file->private_data = mm; | 723 | file->private_data = mm; |
@@ -734,6 +741,9 @@ static ssize_t mem_rw(struct file *file, char __user *buf, | |||
734 | return -ENOMEM; | 741 | return -ENOMEM; |
735 | 742 | ||
736 | copied = 0; | 743 | copied = 0; |
744 | if (!atomic_inc_not_zero(&mm->mm_users)) | ||
745 | goto free; | ||
746 | |||
737 | while (count > 0) { | 747 | while (count > 0) { |
738 | int this_len = min_t(int, count, PAGE_SIZE); | 748 | int this_len = min_t(int, count, PAGE_SIZE); |
739 | 749 | ||
@@ -761,6 +771,8 @@ static ssize_t mem_rw(struct file *file, char __user *buf, | |||
761 | } | 771 | } |
762 | *ppos = addr; | 772 | *ppos = addr; |
763 | 773 | ||
774 | mmput(mm); | ||
775 | free: | ||
764 | free_page((unsigned long) page); | 776 | free_page((unsigned long) page); |
765 | return copied; | 777 | return copied; |
766 | } | 778 | } |
@@ -797,7 +809,7 @@ static int mem_release(struct inode *inode, struct file *file) | |||
797 | { | 809 | { |
798 | struct mm_struct *mm = file->private_data; | 810 | struct mm_struct *mm = file->private_data; |
799 | if (mm) | 811 | if (mm) |
800 | mmput(mm); | 812 | mmdrop(mm); |
801 | return 0; | 813 | return 0; |
802 | } | 814 | } |
803 | 815 | ||