diff options
Diffstat (limited to 'ipc')
| -rw-r--r-- | ipc/mqueue.c | 19 | ||||
| -rw-r--r-- | ipc/shm.c | 9 | ||||
| -rw-r--r-- | ipc/util.c | 18 |
3 files changed, 29 insertions, 17 deletions
diff --git a/ipc/mqueue.c b/ipc/mqueue.c index 68eb857cfdea..d9393f8e4c3e 100644 --- a/ipc/mqueue.c +++ b/ipc/mqueue.c | |||
| @@ -112,13 +112,14 @@ static inline struct mqueue_inode_info *MQUEUE_I(struct inode *inode) | |||
| 112 | static struct inode *mqueue_get_inode(struct super_block *sb, int mode, | 112 | static struct inode *mqueue_get_inode(struct super_block *sb, int mode, |
| 113 | struct mq_attr *attr) | 113 | struct mq_attr *attr) |
| 114 | { | 114 | { |
| 115 | struct user_struct *u = current_user(); | ||
| 115 | struct inode *inode; | 116 | struct inode *inode; |
| 116 | 117 | ||
| 117 | inode = new_inode(sb); | 118 | inode = new_inode(sb); |
| 118 | if (inode) { | 119 | if (inode) { |
| 119 | inode->i_mode = mode; | 120 | inode->i_mode = mode; |
| 120 | inode->i_uid = current->fsuid; | 121 | inode->i_uid = current_fsuid(); |
| 121 | inode->i_gid = current->fsgid; | 122 | inode->i_gid = current_fsgid(); |
| 122 | inode->i_blocks = 0; | 123 | inode->i_blocks = 0; |
| 123 | inode->i_mtime = inode->i_ctime = inode->i_atime = | 124 | inode->i_mtime = inode->i_ctime = inode->i_atime = |
| 124 | CURRENT_TIME; | 125 | CURRENT_TIME; |
| @@ -126,7 +127,6 @@ static struct inode *mqueue_get_inode(struct super_block *sb, int mode, | |||
| 126 | if (S_ISREG(mode)) { | 127 | if (S_ISREG(mode)) { |
| 127 | struct mqueue_inode_info *info; | 128 | struct mqueue_inode_info *info; |
| 128 | struct task_struct *p = current; | 129 | struct task_struct *p = current; |
| 129 | struct user_struct *u = p->user; | ||
| 130 | unsigned long mq_bytes, mq_msg_tblsz; | 130 | unsigned long mq_bytes, mq_msg_tblsz; |
| 131 | 131 | ||
| 132 | inode->i_fop = &mqueue_file_operations; | 132 | inode->i_fop = &mqueue_file_operations; |
| @@ -507,7 +507,7 @@ static void __do_notify(struct mqueue_inode_info *info) | |||
| 507 | sig_i.si_code = SI_MESGQ; | 507 | sig_i.si_code = SI_MESGQ; |
| 508 | sig_i.si_value = info->notify.sigev_value; | 508 | sig_i.si_value = info->notify.sigev_value; |
| 509 | sig_i.si_pid = task_tgid_vnr(current); | 509 | sig_i.si_pid = task_tgid_vnr(current); |
| 510 | sig_i.si_uid = current->uid; | 510 | sig_i.si_uid = current_uid(); |
| 511 | 511 | ||
| 512 | kill_pid_info(info->notify.sigev_signo, | 512 | kill_pid_info(info->notify.sigev_signo, |
| 513 | &sig_i, info->notify_owner); | 513 | &sig_i, info->notify_owner); |
| @@ -594,6 +594,7 @@ static int mq_attr_ok(struct mq_attr *attr) | |||
| 594 | static struct file *do_create(struct dentry *dir, struct dentry *dentry, | 594 | static struct file *do_create(struct dentry *dir, struct dentry *dentry, |
| 595 | int oflag, mode_t mode, struct mq_attr __user *u_attr) | 595 | int oflag, mode_t mode, struct mq_attr __user *u_attr) |
| 596 | { | 596 | { |
| 597 | const struct cred *cred = current_cred(); | ||
| 597 | struct mq_attr attr; | 598 | struct mq_attr attr; |
| 598 | struct file *result; | 599 | struct file *result; |
| 599 | int ret; | 600 | int ret; |
| @@ -618,7 +619,7 @@ static struct file *do_create(struct dentry *dir, struct dentry *dentry, | |||
| 618 | if (ret) | 619 | if (ret) |
| 619 | goto out_drop_write; | 620 | goto out_drop_write; |
| 620 | 621 | ||
| 621 | result = dentry_open(dentry, mqueue_mnt, oflag); | 622 | result = dentry_open(dentry, mqueue_mnt, oflag, cred); |
| 622 | /* | 623 | /* |
| 623 | * dentry_open() took a persistent mnt_want_write(), | 624 | * dentry_open() took a persistent mnt_want_write(), |
| 624 | * so we can now drop this one. | 625 | * so we can now drop this one. |
| @@ -637,8 +638,10 @@ out: | |||
| 637 | /* Opens existing queue */ | 638 | /* Opens existing queue */ |
| 638 | static struct file *do_open(struct dentry *dentry, int oflag) | 639 | static struct file *do_open(struct dentry *dentry, int oflag) |
| 639 | { | 640 | { |
| 640 | static int oflag2acc[O_ACCMODE] = { MAY_READ, MAY_WRITE, | 641 | const struct cred *cred = current_cred(); |
| 641 | MAY_READ | MAY_WRITE }; | 642 | |
| 643 | static const int oflag2acc[O_ACCMODE] = { MAY_READ, MAY_WRITE, | ||
| 644 | MAY_READ | MAY_WRITE }; | ||
| 642 | 645 | ||
| 643 | if ((oflag & O_ACCMODE) == (O_RDWR | O_WRONLY)) { | 646 | if ((oflag & O_ACCMODE) == (O_RDWR | O_WRONLY)) { |
| 644 | dput(dentry); | 647 | dput(dentry); |
| @@ -652,7 +655,7 @@ static int oflag2acc[O_ACCMODE] = { MAY_READ, MAY_WRITE, | |||
| 652 | return ERR_PTR(-EACCES); | 655 | return ERR_PTR(-EACCES); |
| 653 | } | 656 | } |
| 654 | 657 | ||
| 655 | return dentry_open(dentry, mqueue_mnt, oflag); | 658 | return dentry_open(dentry, mqueue_mnt, oflag, cred); |
| 656 | } | 659 | } |
| 657 | 660 | ||
| 658 | asmlinkage long sys_mq_open(const char __user *u_name, int oflag, mode_t mode, | 661 | asmlinkage long sys_mq_open(const char __user *u_name, int oflag, mode_t mode, |
| @@ -366,7 +366,7 @@ static int newseg(struct ipc_namespace *ns, struct ipc_params *params) | |||
| 366 | if (shmflg & SHM_HUGETLB) { | 366 | if (shmflg & SHM_HUGETLB) { |
| 367 | /* hugetlb_file_setup takes care of mlock user accounting */ | 367 | /* hugetlb_file_setup takes care of mlock user accounting */ |
| 368 | file = hugetlb_file_setup(name, size); | 368 | file = hugetlb_file_setup(name, size); |
| 369 | shp->mlock_user = current->user; | 369 | shp->mlock_user = current_user(); |
| 370 | } else { | 370 | } else { |
| 371 | int acctflag = VM_ACCOUNT; | 371 | int acctflag = VM_ACCOUNT; |
| 372 | /* | 372 | /* |
| @@ -752,9 +752,10 @@ asmlinkage long sys_shmctl(int shmid, int cmd, struct shmid_ds __user *buf) | |||
| 752 | goto out_unlock; | 752 | goto out_unlock; |
| 753 | 753 | ||
| 754 | if (!capable(CAP_IPC_LOCK)) { | 754 | if (!capable(CAP_IPC_LOCK)) { |
| 755 | uid_t euid = current_euid(); | ||
| 755 | err = -EPERM; | 756 | err = -EPERM; |
| 756 | if (current->euid != shp->shm_perm.uid && | 757 | if (euid != shp->shm_perm.uid && |
| 757 | current->euid != shp->shm_perm.cuid) | 758 | euid != shp->shm_perm.cuid) |
| 758 | goto out_unlock; | 759 | goto out_unlock; |
| 759 | if (cmd == SHM_LOCK && | 760 | if (cmd == SHM_LOCK && |
| 760 | !current->signal->rlim[RLIMIT_MEMLOCK].rlim_cur) | 761 | !current->signal->rlim[RLIMIT_MEMLOCK].rlim_cur) |
| @@ -766,7 +767,7 @@ asmlinkage long sys_shmctl(int shmid, int cmd, struct shmid_ds __user *buf) | |||
| 766 | goto out_unlock; | 767 | goto out_unlock; |
| 767 | 768 | ||
| 768 | if(cmd==SHM_LOCK) { | 769 | if(cmd==SHM_LOCK) { |
| 769 | struct user_struct * user = current->user; | 770 | struct user_struct *user = current_user(); |
| 770 | if (!is_file_hugepages(shp->shm_file)) { | 771 | if (!is_file_hugepages(shp->shm_file)) { |
| 771 | err = shmem_lock(shp->shm_file, 1, user); | 772 | err = shmem_lock(shp->shm_file, 1, user); |
| 772 | if (!err && !(shp->shm_perm.mode & SHM_LOCKED)){ | 773 | if (!err && !(shp->shm_perm.mode & SHM_LOCKED)){ |
diff --git a/ipc/util.c b/ipc/util.c index 361fd1c96fcf..5a1808c774a2 100644 --- a/ipc/util.c +++ b/ipc/util.c | |||
| @@ -258,6 +258,8 @@ int ipc_get_maxid(struct ipc_ids *ids) | |||
| 258 | 258 | ||
| 259 | int ipc_addid(struct ipc_ids* ids, struct kern_ipc_perm* new, int size) | 259 | int ipc_addid(struct ipc_ids* ids, struct kern_ipc_perm* new, int size) |
| 260 | { | 260 | { |
| 261 | uid_t euid; | ||
| 262 | gid_t egid; | ||
| 261 | int id, err; | 263 | int id, err; |
| 262 | 264 | ||
| 263 | if (size > IPCMNI) | 265 | if (size > IPCMNI) |
| @@ -280,8 +282,9 @@ int ipc_addid(struct ipc_ids* ids, struct kern_ipc_perm* new, int size) | |||
| 280 | 282 | ||
| 281 | ids->in_use++; | 283 | ids->in_use++; |
| 282 | 284 | ||
| 283 | new->cuid = new->uid = current->euid; | 285 | current_euid_egid(&euid, &egid); |
| 284 | new->gid = new->cgid = current->egid; | 286 | new->cuid = new->uid = euid; |
| 287 | new->gid = new->cgid = egid; | ||
| 285 | 288 | ||
| 286 | new->seq = ids->seq++; | 289 | new->seq = ids->seq++; |
| 287 | if(ids->seq > ids->seq_max) | 290 | if(ids->seq > ids->seq_max) |
| @@ -620,13 +623,15 @@ void ipc_rcu_putref(void *ptr) | |||
| 620 | 623 | ||
| 621 | int ipcperms (struct kern_ipc_perm *ipcp, short flag) | 624 | int ipcperms (struct kern_ipc_perm *ipcp, short flag) |
| 622 | { /* flag will most probably be 0 or S_...UGO from <linux/stat.h> */ | 625 | { /* flag will most probably be 0 or S_...UGO from <linux/stat.h> */ |
| 626 | uid_t euid = current_euid(); | ||
| 623 | int requested_mode, granted_mode, err; | 627 | int requested_mode, granted_mode, err; |
| 624 | 628 | ||
| 625 | if (unlikely((err = audit_ipc_obj(ipcp)))) | 629 | if (unlikely((err = audit_ipc_obj(ipcp)))) |
| 626 | return err; | 630 | return err; |
| 627 | requested_mode = (flag >> 6) | (flag >> 3) | flag; | 631 | requested_mode = (flag >> 6) | (flag >> 3) | flag; |
| 628 | granted_mode = ipcp->mode; | 632 | granted_mode = ipcp->mode; |
| 629 | if (current->euid == ipcp->cuid || current->euid == ipcp->uid) | 633 | if (euid == ipcp->cuid || |
| 634 | euid == ipcp->uid) | ||
| 630 | granted_mode >>= 6; | 635 | granted_mode >>= 6; |
| 631 | else if (in_group_p(ipcp->cgid) || in_group_p(ipcp->gid)) | 636 | else if (in_group_p(ipcp->cgid) || in_group_p(ipcp->gid)) |
| 632 | granted_mode >>= 3; | 637 | granted_mode >>= 3; |
| @@ -788,6 +793,7 @@ struct kern_ipc_perm *ipcctl_pre_down(struct ipc_ids *ids, int id, int cmd, | |||
| 788 | struct ipc64_perm *perm, int extra_perm) | 793 | struct ipc64_perm *perm, int extra_perm) |
| 789 | { | 794 | { |
| 790 | struct kern_ipc_perm *ipcp; | 795 | struct kern_ipc_perm *ipcp; |
| 796 | uid_t euid; | ||
| 791 | int err; | 797 | int err; |
| 792 | 798 | ||
| 793 | down_write(&ids->rw_mutex); | 799 | down_write(&ids->rw_mutex); |
| @@ -807,8 +813,10 @@ struct kern_ipc_perm *ipcctl_pre_down(struct ipc_ids *ids, int id, int cmd, | |||
| 807 | if (err) | 813 | if (err) |
| 808 | goto out_unlock; | 814 | goto out_unlock; |
| 809 | } | 815 | } |
| 810 | if (current->euid == ipcp->cuid || | 816 | |
| 811 | current->euid == ipcp->uid || capable(CAP_SYS_ADMIN)) | 817 | euid = current_euid(); |
| 818 | if (euid == ipcp->cuid || | ||
| 819 | euid == ipcp->uid || capable(CAP_SYS_ADMIN)) | ||
| 812 | return ipcp; | 820 | return ipcp; |
| 813 | 821 | ||
| 814 | err = -EPERM; | 822 | err = -EPERM; |
