diff options
| author | Jeff Garzik <jgarzik@pobox.com> | 2005-09-08 05:37:58 -0400 | 
|---|---|---|
| committer | Jeff Garzik <jgarzik@pobox.com> | 2005-09-08 05:37:58 -0400 | 
| commit | 5a2cec83a9bb1b4295aa8ab728fcb8ca1811a33c (patch) | |
| tree | 2f83dc6949763e77cf6422e696dc6146684dcf4e /fs/proc | |
| parent | f2c853bca542f5ac0b036377637192a74f2091c2 (diff) | |
| parent | caf39e87cc1182f7dae84eefc43ca14d54c78ef9 (diff) | |
Merge /spare/repo/linux-2.6/ 
Diffstat (limited to 'fs/proc')
| -rw-r--r-- | fs/proc/base.c | 63 | ||||
| -rw-r--r-- | fs/proc/generic.c | 13 | 
2 files changed, 32 insertions, 44 deletions
| diff --git a/fs/proc/base.c b/fs/proc/base.c index 520978e49e92..84751f3f52d5 100644 --- a/fs/proc/base.c +++ b/fs/proc/base.c | |||
| @@ -119,7 +119,6 @@ enum pid_directory_inos { | |||
| 119 | #ifdef CONFIG_AUDITSYSCALL | 119 | #ifdef CONFIG_AUDITSYSCALL | 
| 120 | PROC_TGID_LOGINUID, | 120 | PROC_TGID_LOGINUID, | 
| 121 | #endif | 121 | #endif | 
| 122 | PROC_TGID_FD_DIR, | ||
| 123 | PROC_TGID_OOM_SCORE, | 122 | PROC_TGID_OOM_SCORE, | 
| 124 | PROC_TGID_OOM_ADJUST, | 123 | PROC_TGID_OOM_ADJUST, | 
| 125 | PROC_TID_INO, | 124 | PROC_TID_INO, | 
| @@ -158,9 +157,11 @@ enum pid_directory_inos { | |||
| 158 | #ifdef CONFIG_AUDITSYSCALL | 157 | #ifdef CONFIG_AUDITSYSCALL | 
| 159 | PROC_TID_LOGINUID, | 158 | PROC_TID_LOGINUID, | 
| 160 | #endif | 159 | #endif | 
| 161 | PROC_TID_FD_DIR = 0x8000, /* 0x8000-0xffff */ | ||
| 162 | PROC_TID_OOM_SCORE, | 160 | PROC_TID_OOM_SCORE, | 
| 163 | PROC_TID_OOM_ADJUST, | 161 | PROC_TID_OOM_ADJUST, | 
| 162 | |||
| 163 | /* Add new entries before this */ | ||
| 164 | PROC_TID_FD_DIR = 0x8000, /* 0x8000-0xffff */ | ||
| 164 | }; | 165 | }; | 
| 165 | 166 | ||
| 166 | struct pid_entry { | 167 | struct pid_entry { | 
| @@ -297,15 +298,21 @@ static int proc_fd_link(struct inode *inode, struct dentry **dentry, struct vfsm | |||
| 297 | return -ENOENT; | 298 | return -ENOENT; | 
| 298 | } | 299 | } | 
| 299 | 300 | ||
| 300 | static int proc_cwd_link(struct inode *inode, struct dentry **dentry, struct vfsmount **mnt) | 301 | static struct fs_struct *get_fs_struct(struct task_struct *task) | 
| 301 | { | 302 | { | 
| 302 | struct fs_struct *fs; | 303 | struct fs_struct *fs; | 
| 303 | int result = -ENOENT; | 304 | task_lock(task); | 
| 304 | task_lock(proc_task(inode)); | 305 | fs = task->fs; | 
| 305 | fs = proc_task(inode)->fs; | ||
| 306 | if(fs) | 306 | if(fs) | 
| 307 | atomic_inc(&fs->count); | 307 | atomic_inc(&fs->count); | 
| 308 | task_unlock(proc_task(inode)); | 308 | task_unlock(task); | 
| 309 | return fs; | ||
| 310 | } | ||
| 311 | |||
| 312 | static int proc_cwd_link(struct inode *inode, struct dentry **dentry, struct vfsmount **mnt) | ||
| 313 | { | ||
| 314 | struct fs_struct *fs = get_fs_struct(proc_task(inode)); | ||
| 315 | int result = -ENOENT; | ||
| 309 | if (fs) { | 316 | if (fs) { | 
| 310 | read_lock(&fs->lock); | 317 | read_lock(&fs->lock); | 
| 311 | *mnt = mntget(fs->pwdmnt); | 318 | *mnt = mntget(fs->pwdmnt); | 
| @@ -319,13 +326,8 @@ static int proc_cwd_link(struct inode *inode, struct dentry **dentry, struct vfs | |||
| 319 | 326 | ||
| 320 | static int proc_root_link(struct inode *inode, struct dentry **dentry, struct vfsmount **mnt) | 327 | static int proc_root_link(struct inode *inode, struct dentry **dentry, struct vfsmount **mnt) | 
| 321 | { | 328 | { | 
| 322 | struct fs_struct *fs; | 329 | struct fs_struct *fs = get_fs_struct(proc_task(inode)); | 
| 323 | int result = -ENOENT; | 330 | int result = -ENOENT; | 
| 324 | task_lock(proc_task(inode)); | ||
| 325 | fs = proc_task(inode)->fs; | ||
| 326 | if(fs) | ||
| 327 | atomic_inc(&fs->count); | ||
| 328 | task_unlock(proc_task(inode)); | ||
| 329 | if (fs) { | 331 | if (fs) { | 
| 330 | read_lock(&fs->lock); | 332 | read_lock(&fs->lock); | 
| 331 | *mnt = mntget(fs->rootmnt); | 333 | *mnt = mntget(fs->rootmnt); | 
| @@ -344,33 +346,6 @@ static int proc_root_link(struct inode *inode, struct dentry **dentry, struct vf | |||
| 344 | (task->state == TASK_STOPPED || task->state == TASK_TRACED) && \ | 346 | (task->state == TASK_STOPPED || task->state == TASK_TRACED) && \ | 
| 345 | security_ptrace(current,task) == 0)) | 347 | security_ptrace(current,task) == 0)) | 
| 346 | 348 | ||
| 347 | static int may_ptrace_attach(struct task_struct *task) | ||
| 348 | { | ||
| 349 | int retval = 0; | ||
| 350 | |||
| 351 | task_lock(task); | ||
| 352 | |||
| 353 | if (!task->mm) | ||
| 354 | goto out; | ||
| 355 | if (((current->uid != task->euid) || | ||
| 356 | (current->uid != task->suid) || | ||
| 357 | (current->uid != task->uid) || | ||
| 358 | (current->gid != task->egid) || | ||
| 359 | (current->gid != task->sgid) || | ||
| 360 | (current->gid != task->gid)) && !capable(CAP_SYS_PTRACE)) | ||
| 361 | goto out; | ||
| 362 | rmb(); | ||
| 363 | if (task->mm->dumpable != 1 && !capable(CAP_SYS_PTRACE)) | ||
| 364 | goto out; | ||
| 365 | if (security_ptrace(current, task)) | ||
| 366 | goto out; | ||
| 367 | |||
| 368 | retval = 1; | ||
| 369 | out: | ||
| 370 | task_unlock(task); | ||
| 371 | return retval; | ||
| 372 | } | ||
| 373 | |||
| 374 | static int proc_pid_environ(struct task_struct *task, char * buffer) | 349 | static int proc_pid_environ(struct task_struct *task, char * buffer) | 
| 375 | { | 350 | { | 
| 376 | int res = 0; | 351 | int res = 0; | 
| @@ -380,7 +355,7 @@ static int proc_pid_environ(struct task_struct *task, char * buffer) | |||
| 380 | if (len > PAGE_SIZE) | 355 | if (len > PAGE_SIZE) | 
| 381 | len = PAGE_SIZE; | 356 | len = PAGE_SIZE; | 
| 382 | res = access_process_vm(task, mm->env_start, buffer, len, 0); | 357 | res = access_process_vm(task, mm->env_start, buffer, len, 0); | 
| 383 | if (!may_ptrace_attach(task)) | 358 | if (!ptrace_may_attach(task)) | 
| 384 | res = -ESRCH; | 359 | res = -ESRCH; | 
| 385 | mmput(mm); | 360 | mmput(mm); | 
| 386 | } | 361 | } | 
| @@ -683,7 +658,7 @@ static ssize_t mem_read(struct file * file, char __user * buf, | |||
| 683 | int ret = -ESRCH; | 658 | int ret = -ESRCH; | 
| 684 | struct mm_struct *mm; | 659 | struct mm_struct *mm; | 
| 685 | 660 | ||
| 686 | if (!MAY_PTRACE(task) || !may_ptrace_attach(task)) | 661 | if (!MAY_PTRACE(task) || !ptrace_may_attach(task)) | 
| 687 | goto out; | 662 | goto out; | 
| 688 | 663 | ||
| 689 | ret = -ENOMEM; | 664 | ret = -ENOMEM; | 
| @@ -709,7 +684,7 @@ static ssize_t mem_read(struct file * file, char __user * buf, | |||
| 709 | 684 | ||
| 710 | this_len = (count > PAGE_SIZE) ? PAGE_SIZE : count; | 685 | this_len = (count > PAGE_SIZE) ? PAGE_SIZE : count; | 
| 711 | retval = access_process_vm(task, src, page, this_len, 0); | 686 | retval = access_process_vm(task, src, page, this_len, 0); | 
| 712 | if (!retval || !MAY_PTRACE(task) || !may_ptrace_attach(task)) { | 687 | if (!retval || !MAY_PTRACE(task) || !ptrace_may_attach(task)) { | 
| 713 | if (!ret) | 688 | if (!ret) | 
| 714 | ret = -EIO; | 689 | ret = -EIO; | 
| 715 | break; | 690 | break; | 
| @@ -747,7 +722,7 @@ static ssize_t mem_write(struct file * file, const char * buf, | |||
| 747 | struct task_struct *task = proc_task(file->f_dentry->d_inode); | 722 | struct task_struct *task = proc_task(file->f_dentry->d_inode); | 
| 748 | unsigned long dst = *ppos; | 723 | unsigned long dst = *ppos; | 
| 749 | 724 | ||
| 750 | if (!MAY_PTRACE(task) || !may_ptrace_attach(task)) | 725 | if (!MAY_PTRACE(task) || !ptrace_may_attach(task)) | 
| 751 | return -ESRCH; | 726 | return -ESRCH; | 
| 752 | 727 | ||
| 753 | page = (char *)__get_free_page(GFP_USER); | 728 | page = (char *)__get_free_page(GFP_USER); | 
| diff --git a/fs/proc/generic.c b/fs/proc/generic.c index abe8920313fb..8a8c34461d48 100644 --- a/fs/proc/generic.c +++ b/fs/proc/generic.c | |||
| @@ -249,6 +249,18 @@ out: | |||
| 249 | return error; | 249 | return error; | 
| 250 | } | 250 | } | 
| 251 | 251 | ||
| 252 | static int proc_getattr(struct vfsmount *mnt, struct dentry *dentry, | ||
| 253 | struct kstat *stat) | ||
| 254 | { | ||
| 255 | struct inode *inode = dentry->d_inode; | ||
| 256 | struct proc_dir_entry *de = PROC_I(inode)->pde; | ||
| 257 | if (de && de->nlink) | ||
| 258 | inode->i_nlink = de->nlink; | ||
| 259 | |||
| 260 | generic_fillattr(inode, stat); | ||
| 261 | return 0; | ||
| 262 | } | ||
| 263 | |||
| 252 | static struct inode_operations proc_file_inode_operations = { | 264 | static struct inode_operations proc_file_inode_operations = { | 
| 253 | .setattr = proc_notify_change, | 265 | .setattr = proc_notify_change, | 
| 254 | }; | 266 | }; | 
| @@ -475,6 +487,7 @@ static struct file_operations proc_dir_operations = { | |||
| 475 | */ | 487 | */ | 
| 476 | static struct inode_operations proc_dir_inode_operations = { | 488 | static struct inode_operations proc_dir_inode_operations = { | 
| 477 | .lookup = proc_lookup, | 489 | .lookup = proc_lookup, | 
| 490 | .getattr = proc_getattr, | ||
| 478 | .setattr = proc_notify_change, | 491 | .setattr = proc_notify_change, | 
| 479 | }; | 492 | }; | 
| 480 | 493 | ||
