From: Daniel Hokka Zakrisson <daniel@hozac.com>
To: linux-kernel@vger.kernel.org
Cc: "Björn Steinbrink" <B.Steinbrink@gmx.de>,
greg@kroah.com, matthew@wil.cx, torvalds@osdl.org
Subject: [PATCH] fs: fcntl_setlease defies lease_init assumptions
Date: Mon, 08 May 2006 01:21:01 +0200 [thread overview]
Message-ID: <445E80DD.9090507@hozac.com> (raw)
fcntl_setlease uses a struct file_lock on the stack to find the
file_lock it's actually looking for. The problem with this approach is
that lease_init will attempt to free the file_lock if the arg argument
is invalid, causing kmem_cache_free to be called with the address of the
on-stack file_lock.
After running the following test-case, it doesn't take long for an i686
machine running 2.6.16.13 to stop responding completely.
2.6.17-rc3-git12 shows similar results, although it takes a bit more
activity before crashing.
Björn Steinbrink also identified a slab leak in the same piece of code,
caused by the fasync_helper call which will allocate a new slab every
time because it uses the wrong structure (the one on the stack) when the
a lease on that file already exists.
#define _GNU_SOURCE
#include <fcntl.h>
#include <stdio.h>
#include <unistd.h>
void die(const char *msg)
{
perror(msg);
exit(1);
}
int main(int argc, char *argv[])
{
int fd;
if (argc == 1)
{
fprintf(stderr, "Usage: %s file\n", argv[0]);
exit(1);
}
fd = open(argv[1], O_RDONLY);
if (fd == -1)
die("open()");
if (fcntl(fd, F_SETLEASE, F_RDLCK) == -1)
die("setlease(RDLCK)");
if (fcntl(fd, F_SETLEASE, F_RDLCK) == -1)
die("setlease(RDLCK2)");
if (fcntl(fd, F_SETLEASE, 5) == -1)
die("setlease(invalid)");
close(fd);
return 0;
}
Signed-off-by: Daniel Hokka Zakrisson <daniel@hozac.com>
---
--- a/fs/locks.c 2006-05-07 00:29:26.000000000 +0200
+++ b/fs/locks.c 2006-05-07 23:29:12.000000000 +0200
@@ -1363,6 +1363,7 @@ static int __setlease(struct file *filp,
goto out;
if (my_before != NULL) {
+ *flp = *my_before;
error = lease->fl_lmops->fl_change(my_before, arg);
goto out;
}
@@ -1433,7 +1434,7 @@ EXPORT_SYMBOL(setlease);
*/
int fcntl_setlease(unsigned int fd, struct file *filp, long arg)
{
- struct file_lock fl, *flp = &fl;
+ struct file_lock *fl, *flp;
struct dentry *dentry = filp->f_dentry;
struct inode *inode = dentry->d_inode;
int error;
@@ -1446,14 +1447,15 @@ int fcntl_setlease(unsigned int fd, stru
if (error)
return error;
- locks_init_lock(&fl);
- error = lease_init(filp, arg, &fl);
+ error = lease_alloc(filp, arg, &fl);
if (error)
return error;
+ flp = fl;
lock_kernel();
error = __setlease(filp, arg, &flp);
+ locks_free_lock(fl);
if (error || arg == F_UNLCK)
goto out_unlock;
next reply other threads:[~2006-05-07 23:20 UTC|newest]
Thread overview: 26+ messages / expand[flat|nested] mbox.gz Atom feed top
2006-05-07 23:21 Daniel Hokka Zakrisson [this message]
2006-05-08 3:33 ` [PATCH] fs: fcntl_setlease defies lease_init assumptions Linus Torvalds
2006-05-08 3:34 ` Linus Torvalds
2006-05-08 8:02 ` Daniel Hokka Zakrisson
2006-05-08 7:57 ` Daniel Hokka Zakrisson
2006-05-08 8:31 ` Pekka Enberg
2006-05-08 8:34 ` Pekka Enberg
2006-05-08 15:12 ` Linus Torvalds
2006-05-08 16:06 ` Pekka Enberg
2006-05-08 16:28 ` Linus Torvalds
2006-05-08 19:36 ` Pekka Enberg
2006-05-09 3:38 ` Christoph Lameter
2006-05-09 3:49 ` Martin J. Bligh
2006-05-09 5:31 ` Christoph Lameter
2006-05-09 6:16 ` Martin J. Bligh
2006-05-09 6:22 ` Manfred Spraul
2006-05-09 6:35 ` Keith Owens
2006-05-09 6:37 ` Nick Piggin
2006-05-09 10:26 ` Pekka J Enberg
2006-05-09 18:25 ` Manfred Spraul
2006-05-09 18:56 ` Linus Torvalds
2006-05-09 19:05 ` Pekka Enberg
2006-05-09 19:15 ` Pekka Enberg
2006-05-09 14:40 ` Linus Torvalds
2006-05-09 23:59 ` Christoph Lameter
2006-05-08 16:36 ` Dave Jones
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=445E80DD.9090507@hozac.com \
--to=daniel@hozac.com \
--cc=B.Steinbrink@gmx.de \
--cc=greg@kroah.com \
--cc=linux-kernel@vger.kernel.org \
--cc=matthew@wil.cx \
--cc=torvalds@osdl.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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.