public inbox for linux-kernel@vger.kernel.org
 help / color / mirror / Atom feed
* vfs-fix-d_path-for-unreachable-paths.patch
@ 2009-09-05 14:22 Valdis.Kletnieks
  2009-09-07  8:30 ` vfs-fix-d_path-for-unreachable-paths.patch Miklos Szeredi
  0 siblings, 1 reply; 6+ messages in thread
From: Valdis.Kletnieks @ 2009-09-05 14:22 UTC (permalink / raw)
  To: Miklos Szeredi, Andrew Morton, John Johansen
  Cc: Matthew Wilcox, Andreas Gruenbacher, Al Viro, Christoph Hellwig,
	linux-kernel

[-- Attachment #1: Type: text/plain, Size: 2078 bytes --]

This patch apparently does something resembling what it's supposed to - the
first few lines of /proc/mounts now looks like:

% head -5 /proc/mounts
rootfs (unreachable)/ rootfs rw 0 0
/dev/root / ext3 rw,seclabel,noatime,nodiratime,user_xattr,acl,data=writeback,us
rquota,grpquota 0 0
/dev /dev tmpfs rw,seclabel,relatime,mode=755 0 0
/proc /proc proc rw,relatime 0 0
/sys /sys sysfs rw,relatime 0 0

The now-unreachable rootfs is the letftover initrd rootfs.

The patch commentary notes:

> This patch addresses all these issues, by prefixing such unreachable paths
> with "(unreachable)".  This isn't perfect since the returned path may
> still be a valid _relative_ path, and applications may not check the
> result of getcwd() for starting with a '/' before using it.

It turns out that some things don't check the contents of /proc/mounts for
starting with a / before using it either:

# /sbin/restorecon -v /etc/passwd
Full path required for exclude: (unreachable)/.

And strace shows it's a read of /proc/mounts, not a getcwd() call:

....
open("/proc/self/task/11479/attr/current", O_RDONLY) = 3
read(3, "staff_u:sysadm_r:setfiles_t:s0\0"..., 4095) = 31
close(3)                                = 0
uname({sys="Linux", node="turing-police.cc.vt.edu", ...}) = 0
open("/proc/mounts", O_RDONLY)          = 3
fstat(3, {st_mode=S_IFREG|0444, st_size=0, ...}) = 0
mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7fe
9ce36a000
read(3, "rootfs (unreachable)/ rootfs rw 0"..., 1024) = 1024
write(2, "Full path required for exclude: ("..., 48) = 48

The added "(unreachable) text also gives /etc/rc0.d/S01halt indigestion,
because it thinks it can do stuff like:

awk '$2 !~ /\/(|dev|proc|selinux|sys)$/ && $1 !~ /^\/dev\/ram/ { print $2 }' \
    /proc/mounts | sort -r | \
  while read line; do
    $UMOUNT -f $line
done

Somebody is buggy here, but I'm not sure who. The initrd for leaving a dangling
reference, the patch for breaking /proc/mounts, or /sbin/restorecon and the
shutdown script for being far too trusting of what the kernel tells it?


[-- Attachment #2: Type: application/pgp-signature, Size: 226 bytes --]

^ permalink raw reply	[flat|nested] 6+ messages in thread
* [PATCH 1/2] vfs: seq_file: add helpers for data filling
@ 2009-09-21 12:48 Miklos Szeredi
  0 siblings, 0 replies; 6+ messages in thread
From: Miklos Szeredi @ 2009-09-21 12:48 UTC (permalink / raw)
  To: Al Viro
  Cc: akpm, linux-fsdevel, linux-kernel, Valdis.Kletnieks, agruen, hch,
	hugh.dickins, matthew

From: Miklos Szeredi <mszeredi@suse.cz>

Add two helpers that allow access to the seq_file's own buffer, but
hide the internal details of seq_files.

This allows easier implementation of special purpose filling
functions.  It also cleans up some existing functions which duplicated
the seq_file logic.

Make these inline functions in seq_file.h, as suggested by Al.

Signed-off-by: Miklos Szeredi <mszeredi@suse.cz>
Acked-by: Hugh Dickins <hugh.dickins@tiscali.co.uk>
---
 fs/seq_file.c            |   74 ++++++++++++++++++++++++-----------------------
 include/linux/seq_file.h |   38 ++++++++++++++++++++++++
 2 files changed, 77 insertions(+), 35 deletions(-)

Index: linux-2.6/fs/seq_file.c
===================================================================
--- linux-2.6.orig/fs/seq_file.c	2009-09-09 13:29:21.000000000 +0200
+++ linux-2.6/fs/seq_file.c	2009-09-21 14:17:10.000000000 +0200
@@ -429,20 +429,21 @@ EXPORT_SYMBOL(mangle_path);
  */
 int seq_path(struct seq_file *m, struct path *path, char *esc)
 {
-	if (m->count < m->size) {
-		char *s = m->buf + m->count;
-		char *p = d_path(path, s, m->size - m->count);
+	char *buf;
+	size_t size = seq_get_buf(m, &buf);
+	int res = -1;
+
+	if (size) {
+		char *p = d_path(path, buf, size);
 		if (!IS_ERR(p)) {
-			s = mangle_path(s, p, esc);
-			if (s) {
-				p = m->buf + m->count;
-				m->count = s - m->buf;
-				return s - p;
-			}
+			char *end = mangle_path(buf, p, esc);
+			if (end)
+				res = end - buf;
 		}
 	}
-	m->count = m->size;
-	return -1;
+	seq_commit(m, res);
+
+	return res;
 }
 EXPORT_SYMBOL(seq_path);
 
@@ -454,26 +455,28 @@ EXPORT_SYMBOL(seq_path);
 int seq_path_root(struct seq_file *m, struct path *path, struct path *root,
 		  char *esc)
 {
-	int err = -ENAMETOOLONG;
-	if (m->count < m->size) {
-		char *s = m->buf + m->count;
+	char *buf;
+	size_t size = seq_get_buf(m, &buf);
+	int res = -ENAMETOOLONG;
+
+	if (size) {
 		char *p;
 
 		spin_lock(&dcache_lock);
-		p = __d_path(path, root, s, m->size - m->count);
+		p = __d_path(path, root, buf, size);
 		spin_unlock(&dcache_lock);
-		err = PTR_ERR(p);
+		res = PTR_ERR(p);
 		if (!IS_ERR(p)) {
-			s = mangle_path(s, p, esc);
-			if (s) {
-				p = m->buf + m->count;
-				m->count = s - m->buf;
-				return 0;
-			}
+			char *end = mangle_path(buf, p, esc);
+			if (end)
+				res = end - buf;
+			else
+				res = -ENAMETOOLONG;
 		}
 	}
-	m->count = m->size;
-	return err;
+	seq_commit(m, res);
+
+	return res < 0 ? res : 0;
 }
 
 /*
@@ -481,20 +484,21 @@ int seq_path_root(struct seq_file *m, st
  */
 int seq_dentry(struct seq_file *m, struct dentry *dentry, char *esc)
 {
-	if (m->count < m->size) {
-		char *s = m->buf + m->count;
-		char *p = dentry_path(dentry, s, m->size - m->count);
+	char *buf;
+	size_t size = seq_get_buf(m, &buf);
+	int res = -1;
+
+	if (size) {
+		char *p = dentry_path(dentry, buf, size);
 		if (!IS_ERR(p)) {
-			s = mangle_path(s, p, esc);
-			if (s) {
-				p = m->buf + m->count;
-				m->count = s - m->buf;
-				return s - p;
-			}
+			char *end = mangle_path(buf, p, esc);
+			if (end)
+				res = end - buf;
 		}
 	}
-	m->count = m->size;
-	return -1;
+	seq_commit(m, res);
+
+	return res;
 }
 
 int seq_bitmap(struct seq_file *m, const unsigned long *bits,
Index: linux-2.6/include/linux/seq_file.h
===================================================================
--- linux-2.6.orig/include/linux/seq_file.h	2009-09-09 13:29:21.000000000 +0200
+++ linux-2.6/include/linux/seq_file.h	2009-09-21 14:15:40.000000000 +0200
@@ -35,6 +35,44 @@ struct seq_operations {
 
 #define SEQ_SKIP 1
 
+/**
+ * seq_get_buf - get buffer to write arbitrary data to
+ * @m: the seq_file handle
+ * @bufp: the beginning of the buffer is stored here
+ *
+ * Return the number of bytes available in the buffer, or zero if
+ * there's no space.
+ */
+static inline size_t seq_get_buf(struct seq_file *m, char **bufp)
+{
+	BUG_ON(m->count > m->size);
+	if (m->count < m->size)
+		*bufp = m->buf + m->count;
+	else
+		*bufp = NULL;
+
+	return m->size - m->count;
+}
+
+/**
+ * seq_commit - commit data to the buffer
+ * @m: the seq_file handle
+ * @num: the number of bytes to commit
+ *
+ * Commit @num bytes of data written to a buffer previously acquired
+ * by seq_buf_get.  To signal an error condition, or that the data
+ * didn't fit in the available space, pass a negative @num value.
+ */
+static inline void seq_commit(struct seq_file *m, int num)
+{
+	if (num < 0) {
+		m->count = m->size;
+	} else {
+		BUG_ON(m->count + num > m->size);
+		m->count += num;
+	}
+}
+
 char *mangle_path(char *s, char *p, char *esc);
 int seq_open(struct file *, const struct seq_operations *);
 ssize_t seq_read(struct file *, char __user *, size_t, loff_t *);

^ permalink raw reply	[flat|nested] 6+ messages in thread

end of thread, other threads:[~2009-09-21 12:48 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2009-09-05 14:22 vfs-fix-d_path-for-unreachable-paths.patch Valdis.Kletnieks
2009-09-07  8:30 ` vfs-fix-d_path-for-unreachable-paths.patch Miklos Szeredi
2009-09-07  8:38   ` [patch 1/2] vfs: seq_file: add helpers for data filling Miklos Szeredi
2009-09-07  8:41     ` [patch 2/2] vfs: revert /proc/mounts to old behavior for unreachable mountpoints Miklos Szeredi
2009-09-09 21:15     ` [patch 1/2] vfs: seq_file: add helpers for data filling Andrew Morton
  -- strict thread matches above, loose matches on Subject: below --
2009-09-21 12:48 [PATCH " Miklos Szeredi

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox