diff options
| author | Tony Luck <tony.luck@intel.com> | 2005-10-20 13:41:44 -0400 |
|---|---|---|
| committer | Tony Luck <tony.luck@intel.com> | 2005-10-20 13:41:44 -0400 |
| commit | 9cec58dc138d6fcad9f447a19c8ff69f6540e667 (patch) | |
| tree | 4fe1cca94fdba8b705c87615bee06d3346f687ce /fs/proc/base.c | |
| parent | 17e5ad6c0ce5a970e2830d0de8bdd60a2f077d38 (diff) | |
| parent | ac9b9c667c2e1194e22ebe0a441ae1c37aaa9b90 (diff) | |
Update from upstream with manual merge of Yasunori Goto's
changes to swiotlb.c made in commit 281dd25cdc0d6903929b79183816d151ea626341
since this file has been moved from arch/ia64/lib/swiotlb.c to
lib/swiotlb.c
Signed-off-by: Tony Luck <tony.luck@intel.com>
Diffstat (limited to 'fs/proc/base.c')
| -rw-r--r-- | fs/proc/base.c | 98 |
1 files changed, 91 insertions, 7 deletions
diff --git a/fs/proc/base.c b/fs/proc/base.c index 23db452ab428..a170450aadb1 100644 --- a/fs/proc/base.c +++ b/fs/proc/base.c | |||
| @@ -103,7 +103,9 @@ enum pid_directory_inos { | |||
| 103 | PROC_TGID_NUMA_MAPS, | 103 | PROC_TGID_NUMA_MAPS, |
| 104 | PROC_TGID_MOUNTS, | 104 | PROC_TGID_MOUNTS, |
| 105 | PROC_TGID_WCHAN, | 105 | PROC_TGID_WCHAN, |
| 106 | #ifdef CONFIG_MMU | ||
| 106 | PROC_TGID_SMAPS, | 107 | PROC_TGID_SMAPS, |
| 108 | #endif | ||
| 107 | #ifdef CONFIG_SCHEDSTATS | 109 | #ifdef CONFIG_SCHEDSTATS |
| 108 | PROC_TGID_SCHEDSTAT, | 110 | PROC_TGID_SCHEDSTAT, |
| 109 | #endif | 111 | #endif |
| @@ -141,7 +143,9 @@ enum pid_directory_inos { | |||
| 141 | PROC_TID_NUMA_MAPS, | 143 | PROC_TID_NUMA_MAPS, |
| 142 | PROC_TID_MOUNTS, | 144 | PROC_TID_MOUNTS, |
| 143 | PROC_TID_WCHAN, | 145 | PROC_TID_WCHAN, |
| 146 | #ifdef CONFIG_MMU | ||
| 144 | PROC_TID_SMAPS, | 147 | PROC_TID_SMAPS, |
| 148 | #endif | ||
| 145 | #ifdef CONFIG_SCHEDSTATS | 149 | #ifdef CONFIG_SCHEDSTATS |
| 146 | PROC_TID_SCHEDSTAT, | 150 | PROC_TID_SCHEDSTAT, |
| 147 | #endif | 151 | #endif |
| @@ -195,7 +199,9 @@ static struct pid_entry tgid_base_stuff[] = { | |||
| 195 | E(PROC_TGID_ROOT, "root", S_IFLNK|S_IRWXUGO), | 199 | E(PROC_TGID_ROOT, "root", S_IFLNK|S_IRWXUGO), |
| 196 | E(PROC_TGID_EXE, "exe", S_IFLNK|S_IRWXUGO), | 200 | E(PROC_TGID_EXE, "exe", S_IFLNK|S_IRWXUGO), |
| 197 | E(PROC_TGID_MOUNTS, "mounts", S_IFREG|S_IRUGO), | 201 | E(PROC_TGID_MOUNTS, "mounts", S_IFREG|S_IRUGO), |
| 202 | #ifdef CONFIG_MMU | ||
| 198 | E(PROC_TGID_SMAPS, "smaps", S_IFREG|S_IRUGO), | 203 | E(PROC_TGID_SMAPS, "smaps", S_IFREG|S_IRUGO), |
| 204 | #endif | ||
| 199 | #ifdef CONFIG_SECURITY | 205 | #ifdef CONFIG_SECURITY |
| 200 | E(PROC_TGID_ATTR, "attr", S_IFDIR|S_IRUGO|S_IXUGO), | 206 | E(PROC_TGID_ATTR, "attr", S_IFDIR|S_IRUGO|S_IXUGO), |
| 201 | #endif | 207 | #endif |
| @@ -235,7 +241,9 @@ static struct pid_entry tid_base_stuff[] = { | |||
| 235 | E(PROC_TID_ROOT, "root", S_IFLNK|S_IRWXUGO), | 241 | E(PROC_TID_ROOT, "root", S_IFLNK|S_IRWXUGO), |
| 236 | E(PROC_TID_EXE, "exe", S_IFLNK|S_IRWXUGO), | 242 | E(PROC_TID_EXE, "exe", S_IFLNK|S_IRWXUGO), |
| 237 | E(PROC_TID_MOUNTS, "mounts", S_IFREG|S_IRUGO), | 243 | E(PROC_TID_MOUNTS, "mounts", S_IFREG|S_IRUGO), |
| 244 | #ifdef CONFIG_MMU | ||
| 238 | E(PROC_TID_SMAPS, "smaps", S_IFREG|S_IRUGO), | 245 | E(PROC_TID_SMAPS, "smaps", S_IFREG|S_IRUGO), |
| 246 | #endif | ||
| 239 | #ifdef CONFIG_SECURITY | 247 | #ifdef CONFIG_SECURITY |
| 240 | E(PROC_TID_ATTR, "attr", S_IFDIR|S_IRUGO|S_IXUGO), | 248 | E(PROC_TID_ATTR, "attr", S_IFDIR|S_IRUGO|S_IXUGO), |
| 241 | #endif | 249 | #endif |
| @@ -340,6 +348,54 @@ static int proc_root_link(struct inode *inode, struct dentry **dentry, struct vf | |||
| 340 | return result; | 348 | return result; |
| 341 | } | 349 | } |
| 342 | 350 | ||
| 351 | |||
| 352 | /* Same as proc_root_link, but this addionally tries to get fs from other | ||
| 353 | * threads in the group */ | ||
| 354 | static int proc_task_root_link(struct inode *inode, struct dentry **dentry, | ||
| 355 | struct vfsmount **mnt) | ||
| 356 | { | ||
| 357 | struct fs_struct *fs; | ||
| 358 | int result = -ENOENT; | ||
| 359 | struct task_struct *leader = proc_task(inode); | ||
| 360 | |||
| 361 | task_lock(leader); | ||
| 362 | fs = leader->fs; | ||
| 363 | if (fs) { | ||
| 364 | atomic_inc(&fs->count); | ||
| 365 | task_unlock(leader); | ||
| 366 | } else { | ||
| 367 | /* Try to get fs from other threads */ | ||
| 368 | task_unlock(leader); | ||
| 369 | read_lock(&tasklist_lock); | ||
| 370 | if (pid_alive(leader)) { | ||
| 371 | struct task_struct *task = leader; | ||
| 372 | |||
| 373 | while ((task = next_thread(task)) != leader) { | ||
| 374 | task_lock(task); | ||
| 375 | fs = task->fs; | ||
| 376 | if (fs) { | ||
| 377 | atomic_inc(&fs->count); | ||
| 378 | task_unlock(task); | ||
| 379 | break; | ||
| 380 | } | ||
| 381 | task_unlock(task); | ||
| 382 | } | ||
| 383 | } | ||
| 384 | read_unlock(&tasklist_lock); | ||
| 385 | } | ||
| 386 | |||
| 387 | if (fs) { | ||
| 388 | read_lock(&fs->lock); | ||
| 389 | *mnt = mntget(fs->rootmnt); | ||
| 390 | *dentry = dget(fs->root); | ||
| 391 | read_unlock(&fs->lock); | ||
| 392 | result = 0; | ||
| 393 | put_fs_struct(fs); | ||
| 394 | } | ||
| 395 | return result; | ||
| 396 | } | ||
| 397 | |||
| 398 | |||
| 343 | #define MAY_PTRACE(task) \ | 399 | #define MAY_PTRACE(task) \ |
| 344 | (task == current || \ | 400 | (task == current || \ |
| 345 | (task->parent == current && \ | 401 | (task->parent == current && \ |
| @@ -471,14 +527,14 @@ static int proc_oom_score(struct task_struct *task, char *buffer) | |||
| 471 | 527 | ||
| 472 | /* permission checks */ | 528 | /* permission checks */ |
| 473 | 529 | ||
| 474 | static int proc_check_root(struct inode *inode) | 530 | /* If the process being read is separated by chroot from the reading process, |
| 531 | * don't let the reader access the threads. | ||
| 532 | */ | ||
| 533 | static int proc_check_chroot(struct dentry *root, struct vfsmount *vfsmnt) | ||
| 475 | { | 534 | { |
| 476 | struct dentry *de, *base, *root; | 535 | struct dentry *de, *base; |
| 477 | struct vfsmount *our_vfsmnt, *vfsmnt, *mnt; | 536 | struct vfsmount *our_vfsmnt, *mnt; |
| 478 | int res = 0; | 537 | int res = 0; |
| 479 | |||
| 480 | if (proc_root_link(inode, &root, &vfsmnt)) /* Ewww... */ | ||
| 481 | return -ENOENT; | ||
| 482 | read_lock(¤t->fs->lock); | 538 | read_lock(¤t->fs->lock); |
| 483 | our_vfsmnt = mntget(current->fs->rootmnt); | 539 | our_vfsmnt = mntget(current->fs->rootmnt); |
| 484 | base = dget(current->fs->root); | 540 | base = dget(current->fs->root); |
| @@ -511,6 +567,16 @@ out: | |||
| 511 | goto exit; | 567 | goto exit; |
| 512 | } | 568 | } |
| 513 | 569 | ||
| 570 | static int proc_check_root(struct inode *inode) | ||
| 571 | { | ||
| 572 | struct dentry *root; | ||
| 573 | struct vfsmount *vfsmnt; | ||
| 574 | |||
| 575 | if (proc_root_link(inode, &root, &vfsmnt)) /* Ewww... */ | ||
| 576 | return -ENOENT; | ||
| 577 | return proc_check_chroot(root, vfsmnt); | ||
| 578 | } | ||
| 579 | |||
| 514 | static int proc_permission(struct inode *inode, int mask, struct nameidata *nd) | 580 | static int proc_permission(struct inode *inode, int mask, struct nameidata *nd) |
| 515 | { | 581 | { |
| 516 | if (generic_permission(inode, mask, NULL) != 0) | 582 | if (generic_permission(inode, mask, NULL) != 0) |
| @@ -518,6 +584,20 @@ static int proc_permission(struct inode *inode, int mask, struct nameidata *nd) | |||
| 518 | return proc_check_root(inode); | 584 | return proc_check_root(inode); |
| 519 | } | 585 | } |
| 520 | 586 | ||
| 587 | static int proc_task_permission(struct inode *inode, int mask, struct nameidata *nd) | ||
| 588 | { | ||
| 589 | struct dentry *root; | ||
| 590 | struct vfsmount *vfsmnt; | ||
| 591 | |||
| 592 | if (generic_permission(inode, mask, NULL) != 0) | ||
| 593 | return -EACCES; | ||
| 594 | |||
| 595 | if (proc_task_root_link(inode, &root, &vfsmnt)) | ||
| 596 | return -ENOENT; | ||
| 597 | |||
| 598 | return proc_check_chroot(root, vfsmnt); | ||
| 599 | } | ||
| 600 | |||
| 521 | extern struct seq_operations proc_pid_maps_op; | 601 | extern struct seq_operations proc_pid_maps_op; |
| 522 | static int maps_open(struct inode *inode, struct file *file) | 602 | static int maps_open(struct inode *inode, struct file *file) |
| 523 | { | 603 | { |
| @@ -558,6 +638,7 @@ static struct file_operations proc_numa_maps_operations = { | |||
| 558 | }; | 638 | }; |
| 559 | #endif | 639 | #endif |
| 560 | 640 | ||
| 641 | #ifdef CONFIG_MMU | ||
| 561 | extern struct seq_operations proc_pid_smaps_op; | 642 | extern struct seq_operations proc_pid_smaps_op; |
| 562 | static int smaps_open(struct inode *inode, struct file *file) | 643 | static int smaps_open(struct inode *inode, struct file *file) |
| 563 | { | 644 | { |
| @@ -576,6 +657,7 @@ static struct file_operations proc_smaps_operations = { | |||
| 576 | .llseek = seq_lseek, | 657 | .llseek = seq_lseek, |
| 577 | .release = seq_release, | 658 | .release = seq_release, |
| 578 | }; | 659 | }; |
| 660 | #endif | ||
| 579 | 661 | ||
| 580 | extern struct seq_operations mounts_op; | 662 | extern struct seq_operations mounts_op; |
| 581 | static int mounts_open(struct inode *inode, struct file *file) | 663 | static int mounts_open(struct inode *inode, struct file *file) |
| @@ -1419,7 +1501,7 @@ static struct inode_operations proc_fd_inode_operations = { | |||
| 1419 | 1501 | ||
| 1420 | static struct inode_operations proc_task_inode_operations = { | 1502 | static struct inode_operations proc_task_inode_operations = { |
| 1421 | .lookup = proc_task_lookup, | 1503 | .lookup = proc_task_lookup, |
| 1422 | .permission = proc_permission, | 1504 | .permission = proc_task_permission, |
| 1423 | }; | 1505 | }; |
| 1424 | 1506 | ||
| 1425 | #ifdef CONFIG_SECURITY | 1507 | #ifdef CONFIG_SECURITY |
| @@ -1609,10 +1691,12 @@ static struct dentry *proc_pident_lookup(struct inode *dir, | |||
| 1609 | case PROC_TGID_MOUNTS: | 1691 | case PROC_TGID_MOUNTS: |
| 1610 | inode->i_fop = &proc_mounts_operations; | 1692 | inode->i_fop = &proc_mounts_operations; |
| 1611 | break; | 1693 | break; |
| 1694 | #ifdef CONFIG_MMU | ||
| 1612 | case PROC_TID_SMAPS: | 1695 | case PROC_TID_SMAPS: |
| 1613 | case PROC_TGID_SMAPS: | 1696 | case PROC_TGID_SMAPS: |
| 1614 | inode->i_fop = &proc_smaps_operations; | 1697 | inode->i_fop = &proc_smaps_operations; |
| 1615 | break; | 1698 | break; |
| 1699 | #endif | ||
| 1616 | #ifdef CONFIG_SECURITY | 1700 | #ifdef CONFIG_SECURITY |
| 1617 | case PROC_TID_ATTR: | 1701 | case PROC_TID_ATTR: |
| 1618 | inode->i_nlink = 2; | 1702 | inode->i_nlink = 2; |
