* [PATCH 1/2] UBIFS: prepare to fix a horrid bug
@ 2013-06-28 11:15 ` Artem Bityutskiy
0 siblings, 0 replies; 8+ messages in thread
From: Artem Bityutskiy @ 2013-06-28 11:15 UTC (permalink / raw)
To: Al Viro; +Cc: MTD Maling List, Linux FS Maling List
From: Artem Bityutskiy <artem.bityutskiy@linux.intel.com>
Al Viro pointed me to the fact that '->readdir()' and '->llseek()' have no
mutual exclusion, which means the 'ubifs_dir_llseek()' can be run while we are
in the middle of 'ubifs_readdir()'.
First of all, this means that 'file->private_data' can be freed while
'ubifs_readdir()' uses it. But this particular patch does not fix the problem.
This patch is only a preparation, and the fix will follow next.
In this patch we make 'ubifs_readdir()' stop using 'file->f_pos' directly,
because 'file->f_pos' can be changed by '->llseek()' at any point. This may
lead 'ubifs_readdir()' to returning inconsistent data: directory entry names
may correspond to incorrect file positions.
So here we introduce a local variable 'pos', read 'file->f_pose' once at very
the beginning, and then stick to 'pos'. The result of this is that when
'ubifs_dir_llseek()' changes 'file->f_pos' while we are in the middle of
'ubifs_readdir()', the latter "wins".
Cc: stable@vger.kernel.org
Reported-by: Al Viro <viro@zeniv.linux.org.uk>
Tested-by: Artem Bityutskiy <artem.bityutskiy@linux.intel.com>
Signed-off-by: Artem Bityutskiy <artem.bityutskiy@linux.intel.com>
---
fs/ubifs/dir.c | 24 ++++++++++++------------
1 files changed, 12 insertions(+), 12 deletions(-)
diff --git a/fs/ubifs/dir.c b/fs/ubifs/dir.c
index de08c92f..8e587af 100644
--- a/fs/ubifs/dir.c
+++ b/fs/ubifs/dir.c
@@ -349,15 +349,16 @@ static unsigned int vfs_dent_type(uint8_t type)
static int ubifs_readdir(struct file *file, void *dirent, filldir_t filldir)
{
int err, over = 0;
+ loff_t pos = file->f_pos;
struct qstr nm;
union ubifs_key key;
struct ubifs_dent_node *dent;
struct inode *dir = file_inode(file);
struct ubifs_info *c = dir->i_sb->s_fs_info;
- dbg_gen("dir ino %lu, f_pos %#llx", dir->i_ino, file->f_pos);
+ dbg_gen("dir ino %lu, f_pos %#llx", dir->i_ino, pos);
- if (file->f_pos > UBIFS_S_KEY_HASH_MASK || file->f_pos == 2)
+ if (pos > UBIFS_S_KEY_HASH_MASK || pos == 2)
/*
* The directory was seek'ed to a senseless position or there
* are no more entries.
@@ -365,15 +366,15 @@ static int ubifs_readdir(struct file *file, void *dirent, filldir_t filldir)
return 0;
/* File positions 0 and 1 correspond to "." and ".." */
- if (file->f_pos == 0) {
+ if (pos == 0) {
ubifs_assert(!file->private_data);
over = filldir(dirent, ".", 1, 0, dir->i_ino, DT_DIR);
if (over)
return 0;
- file->f_pos = 1;
+ file->f_pos = pos = 1;
}
- if (file->f_pos == 1) {
+ if (pos == 1) {
ubifs_assert(!file->private_data);
over = filldir(dirent, "..", 2, 1,
parent_ino(file->f_path.dentry), DT_DIR);
@@ -389,7 +390,7 @@ static int ubifs_readdir(struct file *file, void *dirent, filldir_t filldir)
goto out;
}
- file->f_pos = key_hash_flash(c, &dent->key);
+ file->f_pos = pos = key_hash_flash(c, &dent->key);
file->private_data = dent;
}
@@ -397,17 +398,16 @@ static int ubifs_readdir(struct file *file, void *dirent, filldir_t filldir)
if (!dent) {
/*
* The directory was seek'ed to and is now readdir'ed.
- * Find the entry corresponding to @file->f_pos or the
- * closest one.
+ * Find the entry corresponding to @pos or the closest one.
*/
- dent_key_init_hash(c, &key, dir->i_ino, file->f_pos);
+ dent_key_init_hash(c, &key, dir->i_ino, pos);
nm.name = NULL;
dent = ubifs_tnc_next_ent(c, &key, &nm);
if (IS_ERR(dent)) {
err = PTR_ERR(dent);
goto out;
}
- file->f_pos = key_hash_flash(c, &dent->key);
+ file->f_pos = pos = key_hash_flash(c, &dent->key);
file->private_data = dent;
}
@@ -419,7 +419,7 @@ static int ubifs_readdir(struct file *file, void *dirent, filldir_t filldir)
ubifs_inode(dir)->creat_sqnum);
nm.len = le16_to_cpu(dent->nlen);
- over = filldir(dirent, dent->name, nm.len, file->f_pos,
+ over = filldir(dirent, dent->name, nm.len, pos,
le64_to_cpu(dent->inum),
vfs_dent_type(dent->type));
if (over)
@@ -435,7 +435,7 @@ static int ubifs_readdir(struct file *file, void *dirent, filldir_t filldir)
}
kfree(file->private_data);
- file->f_pos = key_hash_flash(c, &dent->key);
+ file->f_pos = pos = key_hash_flash(c, &dent->key);
file->private_data = dent;
cond_resched();
}
--
1.7.7.6
^ permalink raw reply related [flat|nested] 8+ messages in thread
* [PATCH 1/2] UBIFS: prepare to fix a horrid bug
@ 2013-06-28 11:15 ` Artem Bityutskiy
0 siblings, 0 replies; 8+ messages in thread
From: Artem Bityutskiy @ 2013-06-28 11:15 UTC (permalink / raw)
To: Al Viro; +Cc: Linux FS Maling List, MTD Maling List
From: Artem Bityutskiy <artem.bityutskiy@linux.intel.com>
Al Viro pointed me to the fact that '->readdir()' and '->llseek()' have no
mutual exclusion, which means the 'ubifs_dir_llseek()' can be run while we are
in the middle of 'ubifs_readdir()'.
First of all, this means that 'file->private_data' can be freed while
'ubifs_readdir()' uses it. But this particular patch does not fix the problem.
This patch is only a preparation, and the fix will follow next.
In this patch we make 'ubifs_readdir()' stop using 'file->f_pos' directly,
because 'file->f_pos' can be changed by '->llseek()' at any point. This may
lead 'ubifs_readdir()' to returning inconsistent data: directory entry names
may correspond to incorrect file positions.
So here we introduce a local variable 'pos', read 'file->f_pose' once at very
the beginning, and then stick to 'pos'. The result of this is that when
'ubifs_dir_llseek()' changes 'file->f_pos' while we are in the middle of
'ubifs_readdir()', the latter "wins".
Cc: stable@vger.kernel.org
Reported-by: Al Viro <viro@zeniv.linux.org.uk>
Tested-by: Artem Bityutskiy <artem.bityutskiy@linux.intel.com>
Signed-off-by: Artem Bityutskiy <artem.bityutskiy@linux.intel.com>
---
fs/ubifs/dir.c | 24 ++++++++++++------------
1 files changed, 12 insertions(+), 12 deletions(-)
diff --git a/fs/ubifs/dir.c b/fs/ubifs/dir.c
index de08c92f..8e587af 100644
--- a/fs/ubifs/dir.c
+++ b/fs/ubifs/dir.c
@@ -349,15 +349,16 @@ static unsigned int vfs_dent_type(uint8_t type)
static int ubifs_readdir(struct file *file, void *dirent, filldir_t filldir)
{
int err, over = 0;
+ loff_t pos = file->f_pos;
struct qstr nm;
union ubifs_key key;
struct ubifs_dent_node *dent;
struct inode *dir = file_inode(file);
struct ubifs_info *c = dir->i_sb->s_fs_info;
- dbg_gen("dir ino %lu, f_pos %#llx", dir->i_ino, file->f_pos);
+ dbg_gen("dir ino %lu, f_pos %#llx", dir->i_ino, pos);
- if (file->f_pos > UBIFS_S_KEY_HASH_MASK || file->f_pos == 2)
+ if (pos > UBIFS_S_KEY_HASH_MASK || pos == 2)
/*
* The directory was seek'ed to a senseless position or there
* are no more entries.
@@ -365,15 +366,15 @@ static int ubifs_readdir(struct file *file, void *dirent, filldir_t filldir)
return 0;
/* File positions 0 and 1 correspond to "." and ".." */
- if (file->f_pos == 0) {
+ if (pos == 0) {
ubifs_assert(!file->private_data);
over = filldir(dirent, ".", 1, 0, dir->i_ino, DT_DIR);
if (over)
return 0;
- file->f_pos = 1;
+ file->f_pos = pos = 1;
}
- if (file->f_pos == 1) {
+ if (pos == 1) {
ubifs_assert(!file->private_data);
over = filldir(dirent, "..", 2, 1,
parent_ino(file->f_path.dentry), DT_DIR);
@@ -389,7 +390,7 @@ static int ubifs_readdir(struct file *file, void *dirent, filldir_t filldir)
goto out;
}
- file->f_pos = key_hash_flash(c, &dent->key);
+ file->f_pos = pos = key_hash_flash(c, &dent->key);
file->private_data = dent;
}
@@ -397,17 +398,16 @@ static int ubifs_readdir(struct file *file, void *dirent, filldir_t filldir)
if (!dent) {
/*
* The directory was seek'ed to and is now readdir'ed.
- * Find the entry corresponding to @file->f_pos or the
- * closest one.
+ * Find the entry corresponding to @pos or the closest one.
*/
- dent_key_init_hash(c, &key, dir->i_ino, file->f_pos);
+ dent_key_init_hash(c, &key, dir->i_ino, pos);
nm.name = NULL;
dent = ubifs_tnc_next_ent(c, &key, &nm);
if (IS_ERR(dent)) {
err = PTR_ERR(dent);
goto out;
}
- file->f_pos = key_hash_flash(c, &dent->key);
+ file->f_pos = pos = key_hash_flash(c, &dent->key);
file->private_data = dent;
}
@@ -419,7 +419,7 @@ static int ubifs_readdir(struct file *file, void *dirent, filldir_t filldir)
ubifs_inode(dir)->creat_sqnum);
nm.len = le16_to_cpu(dent->nlen);
- over = filldir(dirent, dent->name, nm.len, file->f_pos,
+ over = filldir(dirent, dent->name, nm.len, pos,
le64_to_cpu(dent->inum),
vfs_dent_type(dent->type));
if (over)
@@ -435,7 +435,7 @@ static int ubifs_readdir(struct file *file, void *dirent, filldir_t filldir)
}
kfree(file->private_data);
- file->f_pos = key_hash_flash(c, &dent->key);
+ file->f_pos = pos = key_hash_flash(c, &dent->key);
file->private_data = dent;
cond_resched();
}
--
1.7.7.6
^ permalink raw reply related [flat|nested] 8+ messages in thread
* [PATCH 2/2] UBIFS: fix a horrid bug
2013-06-28 11:15 ` Artem Bityutskiy
@ 2013-06-28 11:15 ` Artem Bityutskiy
-1 siblings, 0 replies; 8+ messages in thread
From: Artem Bityutskiy @ 2013-06-28 11:15 UTC (permalink / raw)
To: Al Viro; +Cc: MTD Maling List, Linux FS Maling List
From: Artem Bityutskiy <artem.bityutskiy@linux.intel.com>
Al Viro pointed me to the fact that '->readdir()' and '->llseek()' have no
mutual exclusion, which means the 'ubifs_dir_llseek()' can be run while we are
in the middle of 'ubifs_readdir()'.
This means that 'file->private_data' can be freed while 'ubifs_readdir()' uses
it, and this is a very bad bug: not only 'ubifs_readdir()' can return garbage,
but this may corrupt memory and lead to all kinds of problems like crashes an
security holes.
This patch fixes the problem by using the 'file->f_version' field, which
'->llseek()' always unconditionally sets to zero. We set it to 1 in
'ubifs_readdir()' and whenever we detect that it became 0, we know there was a
seek and it is time to clear the state saved in 'file->private_data'.
I tested this patch by writing a user-space program which runds readdir and
seek in parallell. I could easily crash the kernel without these patches, but
could not crash it with these patches.
Cc: stable@vger.kernel.org
Reported-by: Al Viro <viro@zeniv.linux.org.uk>
Tested-by: Artem Bityutskiy <artem.bityutskiy@linux.intel.com>
Signed-off-by: Artem Bityutskiy <artem.bityutskiy@linux.intel.com>
---
fs/ubifs/dir.c | 30 +++++++++++++++++++++++++++---
1 files changed, 27 insertions(+), 3 deletions(-)
diff --git a/fs/ubifs/dir.c b/fs/ubifs/dir.c
index 8e587af..605af51 100644
--- a/fs/ubifs/dir.c
+++ b/fs/ubifs/dir.c
@@ -365,6 +365,24 @@ static int ubifs_readdir(struct file *file, void *dirent, filldir_t filldir)
*/
return 0;
+ if (file->f_version == 0) {
+ /*
+ * The file was seek'ed, which means that @file->private_data
+ * is now invalid. This may also be just the first
+ * 'ubifs_readdir()' invocation, in which case
+ * @file->private_data is NULL, and the below code is
+ * basically a no-op.
+ */
+ kfree(file->private_data);
+ file->private_data = NULL;
+ }
+
+ /*
+ * 'generic_file_llseek()' unconditionally sets @file->f_version to
+ * zero, and we use this for detecting whether the file was seek'ed.
+ */
+ file->f_version = 1;
+
/* File positions 0 and 1 correspond to "." and ".." */
if (pos == 0) {
ubifs_assert(!file->private_data);
@@ -438,6 +456,14 @@ static int ubifs_readdir(struct file *file, void *dirent, filldir_t filldir)
file->f_pos = pos = key_hash_flash(c, &dent->key);
file->private_data = dent;
cond_resched();
+
+ if (file->f_version == 0)
+ /*
+ * The file was seek'ed meanwhile, lets return and start
+ * reading direntries from the new position on the next
+ * invocation.
+ */
+ return 0;
}
out:
@@ -448,15 +474,13 @@ out:
kfree(file->private_data);
file->private_data = NULL;
+ /* 2 is a special value indicating that there are no more direntries */
file->f_pos = 2;
return 0;
}
-/* If a directory is seeked, we have to free saved readdir() state */
static loff_t ubifs_dir_llseek(struct file *file, loff_t offset, int whence)
{
- kfree(file->private_data);
- file->private_data = NULL;
return generic_file_llseek(file, offset, whence);
}
--
1.7.7.6
^ permalink raw reply related [flat|nested] 8+ messages in thread
* [PATCH 2/2] UBIFS: fix a horrid bug
@ 2013-06-28 11:15 ` Artem Bityutskiy
0 siblings, 0 replies; 8+ messages in thread
From: Artem Bityutskiy @ 2013-06-28 11:15 UTC (permalink / raw)
To: Al Viro; +Cc: Linux FS Maling List, MTD Maling List
From: Artem Bityutskiy <artem.bityutskiy@linux.intel.com>
Al Viro pointed me to the fact that '->readdir()' and '->llseek()' have no
mutual exclusion, which means the 'ubifs_dir_llseek()' can be run while we are
in the middle of 'ubifs_readdir()'.
This means that 'file->private_data' can be freed while 'ubifs_readdir()' uses
it, and this is a very bad bug: not only 'ubifs_readdir()' can return garbage,
but this may corrupt memory and lead to all kinds of problems like crashes an
security holes.
This patch fixes the problem by using the 'file->f_version' field, which
'->llseek()' always unconditionally sets to zero. We set it to 1 in
'ubifs_readdir()' and whenever we detect that it became 0, we know there was a
seek and it is time to clear the state saved in 'file->private_data'.
I tested this patch by writing a user-space program which runds readdir and
seek in parallell. I could easily crash the kernel without these patches, but
could not crash it with these patches.
Cc: stable@vger.kernel.org
Reported-by: Al Viro <viro@zeniv.linux.org.uk>
Tested-by: Artem Bityutskiy <artem.bityutskiy@linux.intel.com>
Signed-off-by: Artem Bityutskiy <artem.bityutskiy@linux.intel.com>
---
fs/ubifs/dir.c | 30 +++++++++++++++++++++++++++---
1 files changed, 27 insertions(+), 3 deletions(-)
diff --git a/fs/ubifs/dir.c b/fs/ubifs/dir.c
index 8e587af..605af51 100644
--- a/fs/ubifs/dir.c
+++ b/fs/ubifs/dir.c
@@ -365,6 +365,24 @@ static int ubifs_readdir(struct file *file, void *dirent, filldir_t filldir)
*/
return 0;
+ if (file->f_version == 0) {
+ /*
+ * The file was seek'ed, which means that @file->private_data
+ * is now invalid. This may also be just the first
+ * 'ubifs_readdir()' invocation, in which case
+ * @file->private_data is NULL, and the below code is
+ * basically a no-op.
+ */
+ kfree(file->private_data);
+ file->private_data = NULL;
+ }
+
+ /*
+ * 'generic_file_llseek()' unconditionally sets @file->f_version to
+ * zero, and we use this for detecting whether the file was seek'ed.
+ */
+ file->f_version = 1;
+
/* File positions 0 and 1 correspond to "." and ".." */
if (pos == 0) {
ubifs_assert(!file->private_data);
@@ -438,6 +456,14 @@ static int ubifs_readdir(struct file *file, void *dirent, filldir_t filldir)
file->f_pos = pos = key_hash_flash(c, &dent->key);
file->private_data = dent;
cond_resched();
+
+ if (file->f_version == 0)
+ /*
+ * The file was seek'ed meanwhile, lets return and start
+ * reading direntries from the new position on the next
+ * invocation.
+ */
+ return 0;
}
out:
@@ -448,15 +474,13 @@ out:
kfree(file->private_data);
file->private_data = NULL;
+ /* 2 is a special value indicating that there are no more direntries */
file->f_pos = 2;
return 0;
}
-/* If a directory is seeked, we have to free saved readdir() state */
static loff_t ubifs_dir_llseek(struct file *file, loff_t offset, int whence)
{
- kfree(file->private_data);
- file->private_data = NULL;
return generic_file_llseek(file, offset, whence);
}
--
1.7.7.6
^ permalink raw reply related [flat|nested] 8+ messages in thread
* Re: [PATCH 1/2] UBIFS: prepare to fix a horrid bug
2013-06-28 11:15 ` Artem Bityutskiy
@ 2013-06-28 12:27 ` Joakim Tjernlund
-1 siblings, 0 replies; 8+ messages in thread
From: Joakim Tjernlund @ 2013-06-28 12:27 UTC (permalink / raw)
To: Artem Bityutskiy
Cc: Linux FS Maling List, linux-mtd, MTD Maling List, Al Viro
"linux-mtd" <linux-mtd-bounces@lists.infradead.org> wrote on 2013/06/28
13:15:14:
>
> From: Artem Bityutskiy <artem.bityutskiy@linux.intel.com>
>
> Al Viro pointed me to the fact that '->readdir()' and '->llseek()' have
no
> mutual exclusion, which means the 'ubifs_dir_llseek()' can be run while
we are
> in the middle of 'ubifs_readdir()'.
>
> First of all, this means that 'file->private_data' can be freed while
> 'ubifs_readdir()' uses it. But this particular patch does not fix the
problem.
> This patch is only a preparation, and the fix will follow next.
>
> In this patch we make 'ubifs_readdir()' stop using 'file->f_pos'
directly,
> because 'file->f_pos' can be changed by '->llseek()' at any point. This
may
> lead 'ubifs_readdir()' to returning inconsistent data: directory entry
names
> may correspond to incorrect file positions.
>
> So here we introduce a local variable 'pos', read 'file->f_pose' once at
very
> the beginning, and then stick to 'pos'. The result of this is that when
> 'ubifs_dir_llseek()' changes 'file->f_pos' while we are in the middle of
> 'ubifs_readdir()', the latter "wins".
Ouch, I hope JFFS2 doesn't have the same bug?
Jcoe
______________________________________________________
Linux MTD discussion mailing list
http://lists.infradead.org/mailman/listinfo/linux-mtd/
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH 1/2] UBIFS: prepare to fix a horrid bug
@ 2013-06-28 12:27 ` Joakim Tjernlund
0 siblings, 0 replies; 8+ messages in thread
From: Joakim Tjernlund @ 2013-06-28 12:27 UTC (permalink / raw)
To: Artem Bityutskiy
Cc: Linux FS Maling List, linux-mtd, MTD Maling List, Al Viro
"linux-mtd" <linux-mtd-bounces@lists.infradead.org> wrote on 2013/06/28
13:15:14:
>
> From: Artem Bityutskiy <artem.bityutskiy@linux.intel.com>
>
> Al Viro pointed me to the fact that '->readdir()' and '->llseek()' have
no
> mutual exclusion, which means the 'ubifs_dir_llseek()' can be run while
we are
> in the middle of 'ubifs_readdir()'.
>
> First of all, this means that 'file->private_data' can be freed while
> 'ubifs_readdir()' uses it. But this particular patch does not fix the
problem.
> This patch is only a preparation, and the fix will follow next.
>
> In this patch we make 'ubifs_readdir()' stop using 'file->f_pos'
directly,
> because 'file->f_pos' can be changed by '->llseek()' at any point. This
may
> lead 'ubifs_readdir()' to returning inconsistent data: directory entry
names
> may correspond to incorrect file positions.
>
> So here we introduce a local variable 'pos', read 'file->f_pose' once at
very
> the beginning, and then stick to 'pos'. The result of this is that when
> 'ubifs_dir_llseek()' changes 'file->f_pos' while we are in the middle of
> 'ubifs_readdir()', the latter "wins".
Ouch, I hope JFFS2 doesn't have the same bug?
Jcoe
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH 1/2] UBIFS: prepare to fix a horrid bug
2013-06-28 12:27 ` Joakim Tjernlund
@ 2013-06-28 13:54 ` Al Viro
-1 siblings, 0 replies; 8+ messages in thread
From: Al Viro @ 2013-06-28 13:54 UTC (permalink / raw)
To: Joakim Tjernlund
Cc: Artem Bityutskiy, Linux FS Maling List, MTD Maling List, linux-mtd
On Fri, Jun 28, 2013 at 02:27:58PM +0200, Joakim Tjernlund wrote:
> > So here we introduce a local variable 'pos', read 'file->f_pose' once at
> very
> > the beginning, and then stick to 'pos'. The result of this is that when
> > 'ubifs_dir_llseek()' changes 'file->f_pos' while we are in the middle of
> > 'ubifs_readdir()', the latter "wins".
>
> Ouch, I hope JFFS2 doesn't have the same bug?
FWIW, this class of bugs (f_pos races, *not* kfree-under-us) is dealt with
by switch to saner API - see commits in linux-next marked [readdir] <something>
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH 1/2] UBIFS: prepare to fix a horrid bug
@ 2013-06-28 13:54 ` Al Viro
0 siblings, 0 replies; 8+ messages in thread
From: Al Viro @ 2013-06-28 13:54 UTC (permalink / raw)
To: Joakim Tjernlund
Cc: Linux FS Maling List, linux-mtd, MTD Maling List, Artem Bityutskiy
On Fri, Jun 28, 2013 at 02:27:58PM +0200, Joakim Tjernlund wrote:
> > So here we introduce a local variable 'pos', read 'file->f_pose' once at
> very
> > the beginning, and then stick to 'pos'. The result of this is that when
> > 'ubifs_dir_llseek()' changes 'file->f_pos' while we are in the middle of
> > 'ubifs_readdir()', the latter "wins".
>
> Ouch, I hope JFFS2 doesn't have the same bug?
FWIW, this class of bugs (f_pos races, *not* kfree-under-us) is dealt with
by switch to saner API - see commits in linux-next marked [readdir] <something>
^ permalink raw reply [flat|nested] 8+ messages in thread
end of thread, other threads:[~2013-06-28 13:54 UTC | newest]
Thread overview: 8+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2013-06-28 11:15 [PATCH 1/2] UBIFS: prepare to fix a horrid bug Artem Bityutskiy
2013-06-28 11:15 ` Artem Bityutskiy
2013-06-28 11:15 ` [PATCH 2/2] UBIFS: " Artem Bityutskiy
2013-06-28 11:15 ` Artem Bityutskiy
2013-06-28 12:27 ` [PATCH 1/2] UBIFS: prepare to " Joakim Tjernlund
2013-06-28 12:27 ` Joakim Tjernlund
2013-06-28 13:54 ` Al Viro
2013-06-28 13:54 ` Al Viro
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.