Gentoo Websites Logo
Go to: Gentoo Home Documentation Forums Lists Bugs Planet Store Wiki Get Gentoo!
View | Details | Raw Unified | Return to bug 399243
Collapse All | Expand All

(-)linux-2.6.39-gentoo-r3/fs/proc/base.c (-104 / +40 lines)
Lines 191-255 Link Here
191
	return result;
191
	return result;
192
}
192
}
193
193
194
static struct mm_struct *__check_mem_permission(struct task_struct *task)
195
{
196
	struct mm_struct *mm;
197
198
	mm = get_task_mm(task);
199
	if (!mm)
200
		return ERR_PTR(-EINVAL);
201
194
202
	/*
195
static struct mm_struct *mm_access(struct task_struct *task, unsigned int mode)
203
	 * A task can always look at itself, in case it chooses
204
	 * to use system calls instead of load instructions.
205
	 */
206
	if (task == current)
207
		return mm;
208
209
	/*
210
	 * If current is actively ptrace'ing, and would also be
211
	 * permitted to freshly attach with ptrace now, permit it.
212
	 */
213
	if (task_is_stopped_or_traced(task)) {
214
		int match;
215
		rcu_read_lock();
216
		match = (tracehook_tracer_task(task) == current);
217
		rcu_read_unlock();
218
		if (match && ptrace_may_access(task, PTRACE_MODE_ATTACH))
219
			return mm;
220
	}
221
222
	/*
223
	 * No one else is allowed.
224
	 */
225
	mmput(mm);
226
	return ERR_PTR(-EPERM);
227
}
228
229
/*
230
 * If current may access user memory in @task return a reference to the
231
 * corresponding mm, otherwise ERR_PTR.
232
 */
233
static struct mm_struct *check_mem_permission(struct task_struct *task)
234
{
235
	struct mm_struct *mm;
236
	int err;
237
238
	/*
239
	 * Avoid racing if task exec's as we might get a new mm but validate
240
	 * against old credentials.
241
	 */
242
	err = mutex_lock_killable(&task->signal->cred_guard_mutex);
243
	if (err)
244
		return ERR_PTR(err);
245
246
	mm = __check_mem_permission(task);
247
	mutex_unlock(&task->signal->cred_guard_mutex);
248
249
	return mm;
250
}
251
252
struct mm_struct *mm_for_maps(struct task_struct *task)
253
{
196
{
254
	struct mm_struct *mm;
197
	struct mm_struct *mm;
255
	int err;
198
	int err;
Lines 260-266 Link Here
260
203
261
	mm = get_task_mm(task);
204
	mm = get_task_mm(task);
262
	if (mm && mm != current->mm &&
205
	if (mm && mm != current->mm &&
263
			!ptrace_may_access(task, PTRACE_MODE_READ)) {
206
			!ptrace_may_access(task, mode)) {
264
		mmput(mm);
207
		mmput(mm);
265
		mm = ERR_PTR(-EACCES);
208
		mm = ERR_PTR(-EACCES);
266
	}
209
	}
Lines 269-274 Link Here
269
	return mm;
212
	return mm;
270
}
213
}
271
214
215
struct mm_struct *mm_for_maps(struct task_struct *task)
216
{
217
  return mm_access(task, PTRACE_MODE_READ);
218
}
219
272
static int proc_pid_cmdline(struct task_struct *task, char * buffer)
220
static int proc_pid_cmdline(struct task_struct *task, char * buffer)
273
{
221
{
274
	int res = 0;
222
	int res = 0;
Lines 813-850 Link Here
813
761
814
static int mem_open(struct inode* inode, struct file* file)
762
static int mem_open(struct inode* inode, struct file* file)
815
{
763
{
816
	file->private_data = (void*)((long)current->self_exec_id);
764
	struct task_struct *task = get_proc_task(file->f_path.dentry->d_inode);
765
	struct mm_struct *mm;
766
	
767
	if (!task)
768
	    return -ESRCH;
769
	
770
	mm = mm_access(task, PTRACE_MODE_ATTACH);
771
	put_task_struct(task);
772
	
773
	if (IS_ERR(mm))
774
	    return PTR_ERR(mm);
775
817
	/* OK to pass negative loff_t, we can catch out-of-range */
776
	/* OK to pass negative loff_t, we can catch out-of-range */
818
	file->f_mode |= FMODE_UNSIGNED_OFFSET;
777
	file->f_mode |= FMODE_UNSIGNED_OFFSET;
778
	file->private_data = mm;
779
819
	return 0;
780
	return 0;
820
}
781
}
821
782
822
static ssize_t mem_read(struct file * file, char __user * buf,
783
static ssize_t mem_read(struct file * file, char __user * buf,
823
			size_t count, loff_t *ppos)
784
			size_t count, loff_t *ppos)
824
{
785
{
825
	struct task_struct *task = get_proc_task(file->f_path.dentry->d_inode);
786
	int ret;
826
	char *page;
787
	char *page;
827
	unsigned long src = *ppos;
788
	unsigned long src = *ppos;
828
	int ret = -ESRCH;
789
	struct mm_struct *mm = file->private_data;
829
	struct mm_struct *mm;
830
790
831
	if (!task)
832
		goto out_no_task;
833
791
834
	ret = -ENOMEM;
792
  	if (!mm)
793
        	return 0;
794
835
	page = (char *)__get_free_page(GFP_TEMPORARY);
795
	page = (char *)__get_free_page(GFP_TEMPORARY);
836
	if (!page)
796
	if (!page)
837
		goto out;
797
		 return -ENOMEM;
838
839
	mm = check_mem_permission(task);
840
	ret = PTR_ERR(mm);
841
	if (IS_ERR(mm))
842
		goto out_free;
843
844
	ret = -EIO;
845
 
846
	if (file->private_data != (void*)((long)current->self_exec_id))
847
		goto out_put;
848
798
849
	ret = 0;
799
	ret = 0;
850
 
800
 
Lines 871-883 Link Here
871
	}
821
	}
872
	*ppos = src;
822
	*ppos = src;
873
823
874
out_put:
875
	mmput(mm);
876
out_free:
877
	free_page((unsigned long) page);
824
	free_page((unsigned long) page);
878
out:
879
	put_task_struct(task);
880
out_no_task:
881
	return ret;
825
	return ret;
882
}
826
}
883
827
Lines 886-912 Link Here
886
{
830
{
887
	int copied;
831
	int copied;
888
	char *page;
832
	char *page;
889
	struct task_struct *task = get_proc_task(file->f_path.dentry->d_inode);
890
	unsigned long dst = *ppos;
833
	unsigned long dst = *ppos;
891
	struct mm_struct *mm;
834
	struct mm_struct *mm = file->private_data;
892
893
	copied = -ESRCH;
894
	if (!task)
895
		goto out_no_task;
896
835
897
	mm = check_mem_permission(task);
836
	if (!mm)
898
	copied = PTR_ERR(mm);
837
		return 0;
899
	if (IS_ERR(mm))
900
		goto out_task;
901
902
	copied = -EIO;
903
	if (file->private_data != (void *)((long)current->self_exec_id))
904
		goto out_mm;
905
838
906
	copied = -ENOMEM;
907
	page = (char *)__get_free_page(GFP_TEMPORARY);
839
	page = (char *)__get_free_page(GFP_TEMPORARY);
908
	if (!page)
840
	if (!page)
909
		goto out_mm;
841
		return -ENOMEM;
910
842
911
	copied = 0;
843
	copied = 0;
912
	while (count > 0) {
844
	while (count > 0) {
Lines 930-940 Link Here
930
	}
862
	}
931
	*ppos = dst;
863
	*ppos = dst;
932
	free_page((unsigned long) page);
864
	free_page((unsigned long) page);
933
out_mm:
934
	mmput(mm);
935
out_task:
936
	put_task_struct(task);
937
out_no_task:
938
	return copied;
865
	return copied;
939
}
866
}
940
867
Lines 954-964 Link Here
954
	return file->f_pos;
881
	return file->f_pos;
955
}
882
}
956
883
884
static int mem_release(struct inode *inode, struct file *file)
885
{
886
  struct mm_struct *mm = file->private_data;
887
888
  mmput(mm);
889
  return 0;
890
}
891
957
static const struct file_operations proc_mem_operations = {
892
static const struct file_operations proc_mem_operations = {
958
	.llseek		= mem_lseek,
893
	.llseek		= mem_lseek,
959
	.read		= mem_read,
894
	.read		= mem_read,
960
	.write		= mem_write,
895
	.write		= mem_write,
961
	.open		= mem_open,
896
	.open		= mem_open,
897
	.release	= mem_release,
962
};
898
};
963
899
964
static ssize_t environ_read(struct file *file, char __user *buf,
900
static ssize_t environ_read(struct file *file, char __user *buf,

Return to bug 399243