From: Milton Miller <miltonm@bga.com>
To: Andrew Morton <akpm@digeo.com>
Cc: linux-kernel@vger.kernel.org
Subject: Re: [PATCH] fix CONFIG_DEVFS=y root=<number>
Date: Sun, 5 Jan 2003 01:46:54 -0600 (CST) [thread overview]
Message-ID: <200301050746.h057ksR40850@sullivan.realtime.net> (raw)
In-Reply-To: <3E169D1F.684A35EC@digeo.com>
init/do_mounts.c: In function `do_read_dir':
init/do_mounts.c:335: warning: `n' might be used uninitialized in this function
and it loops trying to intrepret the directory listing :(
After some searching, I realized the directory contents read in were garbage,
looked at that code closer, and found the cause of the problem:
for (bytes = 0; bytes < len; bytes += n) {
- n = sys_getdents64(fd, p + n, len - bytes);
+ n = sys_getdents64(fd, p + bytes, len - bytes);
updated patch below:
# Patch from Milton Miller <miltonm@bga.com>
# Based on discovery work by Adam J. Richter <adam@yggdrasil.com>
# Cleanups by Andrew Morton (akpm@digeo.com)
#
# There's some init-time code which is supposed to read a devfs directory by
# expanding the bufer until the whole directory fits. But the logic is wrong
# and it only works if the whole directory fits into 512 bytes.
#
# So fix that up, and also clean up some coding in there, and rationalise the
# duplicated definition of linux_dirent64.
# --------------------------------------------
#
diff -Nru a/fs/readdir.c b/fs/readdir.c
--- a/fs/readdir.c Sun Jan 5 01:35:40 2003
+++ b/fs/readdir.c Sun Jan 5 01:35:40 2003
@@ -11,6 +11,7 @@
#include <linux/file.h>
#include <linux/smp_lock.h>
#include <linux/fs.h>
+#include <linux/dirent.h>
#include <linux/security.h>
#include <asm/uaccess.h>
@@ -193,17 +194,6 @@
out:
return error;
}
-
-/*
- * And even better one including d_type field and 64bit d_ino and d_off.
- */
-struct linux_dirent64 {
- u64 d_ino;
- s64 d_off;
- unsigned short d_reclen;
- unsigned char d_type;
- char d_name[0];
-};
#define ROUND_UP64(x) (((x)+sizeof(u64)-1) & ~(sizeof(u64)-1))
diff -Nru a/include/linux/dirent.h b/include/linux/dirent.h
--- a/include/linux/dirent.h Sun Jan 5 01:35:40 2003
+++ b/include/linux/dirent.h Sun Jan 5 01:35:40 2003
@@ -16,4 +16,17 @@
char d_name[256];
};
+#ifdef __KERNEL__
+
+struct linux_dirent64 {
+ u64 d_ino;
+ s64 d_off;
+ unsigned short d_reclen;
+ unsigned char d_type;
+ char d_name[0];
+};
+
+#endif /* __KERNEL__ */
+
+
#endif
diff -Nru a/init/do_mounts.c b/init/do_mounts.c
--- a/init/do_mounts.c Sun Jan 5 01:35:40 2003
+++ b/init/do_mounts.c Sun Jan 5 01:35:40 2003
@@ -13,6 +13,7 @@
#include <linux/suspend.h>
#include <linux/root_dev.h>
#include <linux/mount.h>
+#include <linux/dirent.h>
#include <linux/security.h>
#include <linux/nfs_fs.h>
@@ -324,22 +325,32 @@
#endif
#ifdef CONFIG_DEVFS_FS
+
+/*
+ * If the dir will fit in *buf, return its length. If it won't fit, return
+ * zero. Return -ve on error.
+ */
static int __init do_read_dir(int fd, void *buf, int len)
{
long bytes, n;
char *p = buf;
lseek(fd, 0, 0);
- for (bytes = 0, p = buf; bytes < len; bytes += n, p+=n) {
- n = sys_getdents64(fd, p, len - bytes);
+ for (bytes = 0; bytes < len; bytes += n) {
+ n = sys_getdents64(fd, p + bytes, len - bytes);
if (n < 0)
- return -1;
+ return n;
if (n == 0)
return bytes;
}
return 0;
}
+/*
+ * Try to read all of a directory. Returns the contents at *p, which
+ * is kmalloced memory. Returns the number of bytes read at *len. Returns
+ * NULL on error.
+ */
static void * __init read_dir(char *path, int *len)
{
int size;
@@ -349,7 +360,7 @@
if (fd < 0)
return NULL;
- for (size = 1<<9; size < (1<<18); size <<= 1) {
+ for (size = 1 << 9; size <= (1 << MAX_ORDER); size <<= 1) {
void *p = kmalloc(size, GFP_KERNEL);
int n;
if (!p)
@@ -361,6 +372,8 @@
return p;
}
kfree(p);
+ if (n == -EINVAL)
+ continue; /* Try a larger buffer */
if (n < 0)
break;
}
@@ -368,14 +381,6 @@
return NULL;
}
#endif
-
-struct linux_dirent64 {
- u64 d_ino;
- s64 d_off;
- unsigned short d_reclen;
- unsigned char d_type;
- char d_name[0];
-};
static int __init find_in_devfs(char *path, dev_t dev)
{
prev parent reply other threads:[~2003-01-05 7:38 UTC|newest]
Thread overview: 3+ messages / expand[flat|nested] mbox.gz Atom feed top
2003-01-04 8:01 Milton Miller
2003-01-04 8:36 ` Andrew Morton
2003-01-05 7:46 ` Milton Miller [this message]
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=200301050746.h057ksR40850@sullivan.realtime.net \
--to=miltonm@bga.com \
--cc=akpm@digeo.com \
--cc=linux-kernel@vger.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®