From: Hugh Dickins <hugh@veritas.com>
To: David Wilk <davidwilk@gmail.com>
Cc: Greg KH <greg@kroah.com>, Chris Wright <chrisw@sous-sol.org>,
Marcelo Tosatti <marcelo.tosatti@cyclades.com>,
stable@kernel.org, linux-kernel@vger.kernel.org
Subject: Re: [stable] 2.6.16.6 breaks java... sort of
Date: Thu, 20 Apr 2006 17:24:10 +0100 (BST) [thread overview]
Message-ID: <Pine.LNX.4.64.0604201706540.14395@blonde.wat.veritas.com> (raw)
In-Reply-To: <Pine.LNX.4.64.0604192046590.17491@blonde.wat.veritas.com>
On Wed, 19 Apr 2006, Hugh Dickins wrote:
> On Wed, 19 Apr 2006, Greg KH wrote:
> > On Wed, Apr 19, 2006 at 12:52:33PM -0600, David Wilk wrote:
> > >
> > > I think an issue was introduced with mprotect (the first patch in
> > > 2.6.16.6). With 2.6.16.5, tomcat runs fine (in sun-1.5), but in
> > > 2.6.16.7, the JVM bails out complaining that it couldn't allocate
> > > enough heap space.
>
> Neither expected nor satisfactory. Sorry about that. We were hoping
> the straightforward shm/mprotect fix would be good enough, but it
> appears not. JVM is probably doing something we can allow with a
> more complicated patch, but it _might_ turn out to be doing something
> we simply cannot allow: I'll hope for the first and work out a patch
> for that; but won't be ready to post it until tomorrow.
David, would you please try this patch on top of your 2.6.16.7 or later.
The first hunk undoes the problematic patch, the remainder does it in a
more permissive way. Aesthetically, not as satisfactory as the previous
patch; but it's important that we not break userspace, unless security
absolutely demands. Please let us know how this fares: thanks.
Hugh
--- 2.6.16.9/ipc/shm.c 2006-04-20 11:59:03.000000000 +0100
+++ linux/ipc/shm.c 2006-04-20 16:57:36.000000000 +0100
@@ -161,8 +161,6 @@ static int shm_mmap(struct file * file,
ret = shmem_mmap(file, vma);
if (ret == 0) {
vma->vm_ops = &shm_vm_ops;
- if (!(vma->vm_flags & VM_WRITE))
- vma->vm_flags &= ~VM_MAYWRITE;
shm_inc(file->f_dentry->d_inode->i_ino);
}
@@ -677,6 +675,8 @@ out:
*/
long do_shmat(int shmid, char __user *shmaddr, int shmflg, ulong *raddr)
{
+ struct mm_struct *mm = current->mm;
+ struct vm_area_struct *vma;
struct shmid_kernel *shp;
unsigned long addr;
unsigned long size;
@@ -684,7 +684,7 @@ long do_shmat(int shmid, char __user *sh
int err;
unsigned long flags;
unsigned long prot;
- unsigned long o_flags;
+ int maywrite;
int acc_mode;
void *user_addr;
@@ -711,11 +711,11 @@ long do_shmat(int shmid, char __user *sh
if (shmflg & SHM_RDONLY) {
prot = PROT_READ;
- o_flags = O_RDONLY;
+ maywrite = 0;
acc_mode = S_IRUGO;
} else {
prot = PROT_READ | PROT_WRITE;
- o_flags = O_RDWR;
+ maywrite = 1;
acc_mode = S_IRUGO | S_IWUGO;
}
if (shmflg & SHM_EXEC) {
@@ -748,30 +748,43 @@ long do_shmat(int shmid, char __user *sh
shm_unlock(shp);
return err;
}
-
+
+ if (!maywrite && !ipcperms_dac(&shp->shm_perm, S_IWUGO))
+ maywrite = 1;
+
file = shp->shm_file;
size = i_size_read(file->f_dentry->d_inode);
shp->shm_nattch++;
shm_unlock(shp);
- down_write(¤t->mm->mmap_sem);
+ down_write(&mm->mmap_sem);
if (addr && !(shmflg & SHM_REMAP)) {
user_addr = ERR_PTR(-EINVAL);
- if (find_vma_intersection(current->mm, addr, addr + size))
+ if (find_vma_intersection(mm, addr, addr + size))
goto invalid;
/*
* If shm segment goes below stack, make sure there is some
* space left for the stack to grow (at least 4 pages).
*/
- if (addr < current->mm->start_stack &&
- addr > current->mm->start_stack - size - PAGE_SIZE * 5)
+ if (addr < mm->start_stack &&
+ addr > mm->start_stack - size - PAGE_SIZE * 5)
goto invalid;
}
-
+
user_addr = (void*) do_mmap (file, addr, size, prot, flags, 0);
+ if (!maywrite && !IS_ERR(user_addr)) {
+ /*
+ * Prevent mprotect from giving write permission later on.
+ * We would prefer just to clear VM_MAYWRITE from a readonly
+ * attachment in shm_mmap, but it seems that JVM has got into
+ * the habit of attaching readonly then mprotecting to write.
+ */
+ vma = find_vma(mm, (unsigned long) user_addr);
+ vma->vm_flags &= ~VM_MAYWRITE;
+ }
invalid:
- up_write(¤t->mm->mmap_sem);
+ up_write(&mm->mmap_sem);
down (&shm_ids.sem);
if(!(shp = shm_lock(shmid)))
--- 2.6.16.9/ipc/util.c 2006-03-20 05:53:29.000000000 +0000
+++ linux/ipc/util.c 2006-04-20 16:57:36.000000000 +0100
@@ -464,7 +464,7 @@ void ipc_rcu_putref(void *ptr)
* to ipc resources. return 0 if allowed
*/
-int ipcperms (struct kern_ipc_perm *ipcp, short flag)
+int ipcperms_dac(struct kern_ipc_perm *ipcp, short flag)
{ /* flag will most probably be 0 or S_...UGO from <linux/stat.h> */
int requested_mode, granted_mode;
@@ -478,7 +478,13 @@ int ipcperms (struct kern_ipc_perm *ipcp
if ((requested_mode & ~granted_mode & 0007) &&
!capable(CAP_IPC_OWNER))
return -1;
+ return 0;
+}
+int ipcperms(struct kern_ipc_perm *ipcp, short flag)
+{
+ if (ipcperms_dac(ipcp, flag))
+ return -1;
return security_ipc_permission(ipcp, flag);
}
--- 2.6.16.9/ipc/util.h 2006-03-20 05:53:29.000000000 +0000
+++ linux/ipc/util.h 2006-04-20 16:57:36.000000000 +0100
@@ -47,7 +47,8 @@ int ipc_addid(struct ipc_ids* ids, struc
/* must be called with both locks acquired. */
struct kern_ipc_perm* ipc_rmid(struct ipc_ids* ids, int id);
-int ipcperms (struct kern_ipc_perm *ipcp, short flg);
+int ipcperms_dac(struct kern_ipc_perm *ipcp, short flag);
+int ipcperms(struct kern_ipc_perm *ipcp, short flag);
/* for rare, potentially huge allocations.
* both function can sleep
next prev parent reply other threads:[~2006-04-20 16:25 UTC|newest]
Thread overview: 16+ messages / expand[flat|nested] mbox.gz Atom feed top
[not found] <a4403ff60604191152u5a71e70fr9f54c104a654fc99@mail.gmail.com>
2006-04-19 19:28 ` Greg KH
2006-04-19 19:57 ` Hugh Dickins
2006-04-20 16:24 ` Hugh Dickins [this message]
2006-04-20 17:10 ` David Wilk
2006-04-21 19:08 ` David Wilk
2006-04-21 19:27 ` Chris Wright
2006-04-21 20:43 ` David Wilk
2006-04-21 21:56 ` David Wilk
2006-04-23 12:41 ` Hugh Dickins
2006-04-24 20:59 ` David Wilk
2006-04-25 17:51 ` Hugh Dickins
2006-04-25 18:08 ` David Wilk
2006-04-25 18:28 ` Hugh Dickins
2006-04-26 5:12 ` Andi Kleen
2006-04-26 8:03 ` Adrian Bunk
2006-04-26 21:40 ` David Wilk
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=Pine.LNX.4.64.0604201706540.14395@blonde.wat.veritas.com \
--to=hugh@veritas.com \
--cc=chrisw@sous-sol.org \
--cc=davidwilk@gmail.com \
--cc=greg@kroah.com \
--cc=linux-kernel@vger.kernel.org \
--cc=marcelo.tosatti@cyclades.com \
--cc=stable@kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®