linux-ext4.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 1/2] debugfs: build read-only variant of debugfs
@ 2011-11-15  5:05 Theodore Ts'o
  2011-11-15  5:05 ` [PATCH] libquota: log an error message if ext2fs_file_open() fails Theodore Ts'o
                   ` (2 more replies)
  0 siblings, 3 replies; 5+ messages in thread
From: Theodore Ts'o @ 2011-11-15  5:05 UTC (permalink / raw)
  To: Ext4 Developers List; +Cc: Theodore Ts'o

Create a version of debugfs which only supports read-only examination
of the file system metadata (but not the data blocks).  The idea is
that this version of debugfs might be suitable to be setuid root, and
executable only by members of a particular group, or setgid disk, and
globally executable, depending on the security/privacy policies in
force at a particular site.

Signed-off-by: "Theodore Ts'o" <tytso@mit.edu>
---
 debugfs/Makefile.in      |   20 ++++++++++-
 debugfs/debugfs.c        |   53 ++++++++++++++++++++++++++---
 debugfs/ro_debug_cmds.ct |   85 ++++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 151 insertions(+), 7 deletions(-)
 create mode 100644 debugfs/ro_debug_cmds.ct

diff --git a/debugfs/Makefile.in b/debugfs/Makefile.in
index e314b91..4674ba6 100644
--- a/debugfs/Makefile.in
+++ b/debugfs/Makefile.in
@@ -11,7 +11,7 @@ INSTALL = @INSTALL@
 
 @MCONFIG@
 
-PROGS=		debugfs
+PROGS=		debugfs rdebugfs
 MANPAGES=	debugfs.8
 
 MK_CMDS=	_SS_DIR_OVERRIDE=../lib/ss ../lib/ss/mk_cmds
@@ -19,6 +19,9 @@ MK_CMDS=	_SS_DIR_OVERRIDE=../lib/ss ../lib/ss/mk_cmds
 DEBUG_OBJS= debug_cmds.o debugfs.o util.o ncheck.o icheck.o ls.o \
 	lsdel.o dump.o set_fields.o logdump.o htree.o unused.o
 
+RO_DEBUG_OBJS= ro_debug_cmds.o ro_debugfs.o util.o ncheck.o icheck.o ls.o \
+	lsdel.o logdump.o htree.o
+
 SRCS= debug_cmds.c $(srcdir)/debugfs.c $(srcdir)/util.c $(srcdir)/ls.c \
 	$(srcdir)/ncheck.c $(srcdir)/icheck.c $(srcdir)/lsdel.c \
 	$(srcdir)/dump.c $(srcdir)/set_fields.c ${srcdir}/logdump.c \
@@ -39,10 +42,22 @@ debugfs: $(DEBUG_OBJS) $(DEPLIBS)
 	$(E) "	LD $@"
 	$(Q) $(CC) $(ALL_LDFLAGS) -o debugfs $(DEBUG_OBJS) $(LIBS)
 
+rdebugfs: $(RO_DEBUG_OBJS) $(DEPLIBS)
+	$(E) "	LD $@"
+	$(Q) $(CC) $(ALL_LDFLAGS) -o rdebugfs $(RO_DEBUG_OBJS) $(LIBS)
+
 debug_cmds.c debug_cmds.h: debug_cmds.ct
 	$(E) "	MK_CMDS $@"
 	$(Q) $(MK_CMDS) $(srcdir)/debug_cmds.ct
 
+ro_debug_cmds.c ro_debug_cmds.h: ro_debug_cmds.ct
+	$(E) "	MK_CMDS $@"
+	$(Q) $(MK_CMDS) $(srcdir)/ro_debug_cmds.ct
+
+ro_debugfs.o: debugfs.c
+	$(E) "	CC $@"
+	$(Q) $(CC) -c $(ALL_CFLAGS) $< -DREAD_ONLY -o $@
+
 debugfs.8: $(DEP_SUBSTITUTE) $(srcdir)/debugfs.8.in
 	$(E) "	SUBST $@"
 	$(Q) $(SUBSTITUTE_UPTIME) $(srcdir)/debugfs.8.in debugfs.8
@@ -80,7 +95,8 @@ uninstall:
 	done
 
 clean:
-	$(RM) -f debugfs debugfs.8 \#* *.s *.o *.a *~ debug_cmds.c core
+	$(RM) -f $(PROGS) debugfs.8 \#* *.s *.o *.a *~ debug_cmds.c \
+		ro_debug_cmds.c core
 
 mostlyclean: clean
 distclean: clean
diff --git a/debugfs/debugfs.c b/debugfs/debugfs.c
index 1fb8f44..fda8d92 100644
--- a/debugfs/debugfs.c
+++ b/debugfs/debugfs.c
@@ -140,7 +140,11 @@ void do_open_filesys(int argc, char **argv)
 			open_flags |= EXT2_FLAG_IMAGE_FILE;
 			break;
 		case 'w':
+#ifdef READ_ONLY
+			goto print_usage;
+#else
 			open_flags |= EXT2_FLAG_RW;
+#endif /* READ_ONLY */
 			break;
 		case 'f':
 			open_flags |= EXT2_FLAG_FORCE;
@@ -184,8 +188,11 @@ void do_open_filesys(int argc, char **argv)
 	return;
 
 print_usage:
-	fprintf(stderr, "%s: Usage: open [-s superblock] [-b blocksize] "
-		"[-c] [-w] <device>\n", argv[0]);
+	fprintf(stderr, "%s: Usage: open [-s superblock] [-b blocksize] [-c] "
+#ifndef READ_ONLY
+		"[-w] "
+#endif
+		"<device>\n", argv[0]);
 }
 
 void do_lcd(int argc, char **argv)
@@ -251,6 +258,7 @@ void do_close_filesys(int argc, char **argv)
 	close_filesystem();
 }
 
+#ifndef READ_ONLY
 void do_init_filesys(int argc, char **argv)
 {
 	struct ext2_super_block param;
@@ -276,6 +284,7 @@ void do_init_filesys(int argc, char **argv)
 	root = cwd = EXT2_ROOT_INO;
 	return;
 }
+#endif /* READ_ONLY */
 
 static void print_features(struct ext2_super_block * s, FILE *f)
 {
@@ -393,6 +402,7 @@ print_usage:
 	fprintf(stderr, "%s: Usage: show_super [-h]\n", argv[0]);
 }
 
+#ifndef READ_ONLY
 void do_dirty_filesys(int argc EXT2FS_ATTR((unused)),
 		      char **argv EXT2FS_ATTR((unused)))
 {
@@ -407,6 +417,7 @@ void do_dirty_filesys(int argc EXT2FS_ATTR((unused)),
 		current_fs->super->s_state &= ~EXT2_VALID_FS;
 	ext2fs_mark_super_dirty(current_fs);
 }
+#endif /* READ_ONLY */
 
 struct list_blocks_struct {
 	FILE		*f;
@@ -964,6 +975,7 @@ void do_chroot(int argc, char *argv[])
 	root = inode;
 }
 
+#ifndef READ_ONLY
 void do_clri(int argc, char *argv[])
 {
 	ext2_ino_t inode;
@@ -1006,6 +1018,7 @@ void do_seti(int argc, char *argv[])
 	ext2fs_mark_inode_bitmap2(current_fs->inode_map,inode);
 	ext2fs_mark_ib_dirty(current_fs);
 }
+#endif /* READ_ONLY */
 
 void do_testi(int argc, char *argv[])
 {
@@ -1020,6 +1033,7 @@ void do_testi(int argc, char *argv[])
 		printf("Inode %u is not in use\n", inode);
 }
 
+#ifndef READ_ONLY
 void do_freeb(int argc, char *argv[])
 {
 	blk64_t block;
@@ -1057,6 +1071,7 @@ void do_setb(int argc, char *argv[])
 	}
 	ext2fs_mark_bb_dirty(current_fs);
 }
+#endif /* READ_ONLY */
 
 void do_testb(int argc, char *argv[])
 {
@@ -1074,6 +1089,7 @@ void do_testb(int argc, char *argv[])
 	}
 }
 
+#ifndef READ_ONLY
 static void modify_u8(char *com, const char *prompt,
 		      const char *format, __u8 *val)
 {
@@ -1217,6 +1233,7 @@ void do_modify_inode(int argc, char *argv[])
 	if (debugfs_write_inode(inode_num, &inode, argv[1]))
 		return;
 }
+#endif /* READ_ONLY */
 
 void do_change_working_dir(int argc, char *argv[])
 {
@@ -1298,6 +1315,7 @@ static int ext2_file_type(unsigned int mode)
 	return 0;
 }
 
+#ifndef READ_ONLY
 static void make_link(char *sourcename, char *destname)
 {
 	ext2_ino_t	ino;
@@ -1445,6 +1463,7 @@ void do_unlink(int argc, char *argv[])
 
 	unlink_file_by_name(argv[1]);
 }
+#endif /* READ_ONLY */
 
 void do_find_free_block(int argc, char *argv[])
 {
@@ -1537,6 +1556,7 @@ void do_find_free_inode(int argc, char *argv[])
 		printf("Free inode found: %u\n", free_inode);
 }
 
+#ifndef READ_ONLY
 static errcode_t copy_file(int fd, ext2_ino_t newfile)
 {
 	ext2_file_t	e2_file;
@@ -1944,6 +1964,7 @@ void do_rmdir(int argc, char *argv[])
 			return;
 	}
 }
+#endif /* READ_ONLY */
 
 void do_show_debugfs_params(int argc EXT2FS_ATTR((unused)),
 			    char *argv[] EXT2FS_ATTR((unused)))
@@ -1957,6 +1978,7 @@ void do_show_debugfs_params(int argc EXT2FS_ATTR((unused)),
 		current_fs ? current_fs->device_name : "--none--");
 }
 
+#ifndef READ_ONLY
 void do_expand_dir(int argc, char *argv[])
 {
 	ext2_ino_t inode;
@@ -1990,6 +2012,7 @@ void do_features(int argc, char *argv[])
 	}
 	print_features(current_fs->super, stdout);
 }
+#endif /* READ_ONLY */
 
 void do_bmap(int argc, char *argv[])
 {
@@ -2047,6 +2070,7 @@ void do_imap(int argc, char *argv[])
 
 }
 
+#ifndef READ_ONLY
 void do_set_current_time(int argc, char *argv[])
 {
 	time_t now;
@@ -2066,6 +2090,7 @@ void do_set_current_time(int argc, char *argv[])
 		current_fs->now = now;
 	}
 }
+#endif /* READ_ONLY */
 
 static int find_supp_feature(__u32 *supp, int feature_type, char *name)
 {
@@ -2132,6 +2157,7 @@ void do_supported_features(int argc, char *argv[])
 	}
 }
 
+#ifndef READ_ONLY
 void do_punch(int argc, char *argv[])
 {
 	ext2_ino_t	ino;
@@ -2162,6 +2188,7 @@ void do_punch(int argc, char *argv[])
 		return;
 	}
 }
+#endif /* READ_ONLY */
 
 void do_dump_mmp(int argc, char *argv[])
 {
@@ -2256,7 +2283,13 @@ int main(int argc, char **argv)
 {
 	int		retval;
 	int		sci_idx;
-	const char	*usage = "Usage: %s [-b blocksize] [-s superblock] [-f cmd_file] [-R request] [-V] [[-w] [-c] device]";
+	const char	*usage = 
+		"Usage: %s [-b blocksize] [-s superblock] [-f cmd_file] "
+		"[-R request] [-V] ["
+#ifndef READ_ONLY
+		"[-w] "
+#endif
+		"[-c] device]";
 	int		c;
 	int		open_flags = EXT2_FLAG_SOFTSUPP_FEATURES | EXT2_FLAG_64BITS;
 	char		*request = 0;
@@ -2266,15 +2299,23 @@ int main(int argc, char **argv)
 	blk64_t		blocksize = 0;
 	int		catastrophic = 0;
 	char		*data_filename = 0;
+#ifdef READ_ONLY
+	const char	*opt_string = "iwcR:f:b:s:Vd:D";
+#else
+	const char	*opt_string = "icR:f:b:s:Vd:D";
+#endif
 
 	if (debug_prog_name == 0)
+#ifdef READ_ONLY
+		debug_prog_name = "rdebugfs";
+#else
 		debug_prog_name = "debugfs";
-
+#endif
 	add_error_table(&et_ext2_error_table);
 	fprintf (stderr, "%s %s (%s)\n", debug_prog_name,
 		 E2FSPROGS_VERSION, E2FSPROGS_DATE);
 
-	while ((c = getopt (argc, argv, "iwcR:f:b:s:Vd:D")) != EOF) {
+	while ((c = getopt (argc, argv, opt_string)) != EOF) {
 		switch (c) {
 		case 'R':
 			request = optarg;
@@ -2288,9 +2329,11 @@ int main(int argc, char **argv)
 		case 'i':
 			open_flags |= EXT2_FLAG_IMAGE_FILE;
 			break;
+#ifndef READ_ONLY
 		case 'w':
 			open_flags |= EXT2_FLAG_RW;
 			break;
+#endif
 		case 'D':
 			open_flags |= EXT2_FLAG_DIRECT_IO;
 			break;
diff --git a/debugfs/ro_debug_cmds.ct b/debugfs/ro_debug_cmds.ct
new file mode 100644
index 0000000..4b16a67
--- /dev/null
+++ b/debugfs/ro_debug_cmds.ct
@@ -0,0 +1,85 @@
+#
+# Restricted set of debugfs commands
+#
+# Copyright (C) 1993 Theodore Ts'o.  This file may be redistributed
+# under the terms of the GNU Public License.
+#
+command_table debug_cmds;
+
+request do_show_debugfs_params, "Show debugfs parameters",
+	show_debugfs_params, params;
+
+request do_open_filesys, "Open a filesystem",
+	open_filesys, open;
+
+request do_close_filesys, "Close the filesystem",
+	close_filesys, close;
+
+request do_show_super_stats, "Show superblock statistics",
+	show_super_stats, stats;
+
+request do_ncheck, "Do inode->name translation",
+	ncheck;
+
+request do_icheck, "Do block->inode translation",
+	icheck;
+
+request do_chroot, "Change root directory",
+	change_root_directory, chroot;
+
+request do_change_working_dir, "Change working directory",
+	change_working_directory, cd;
+
+request do_list_dir, "List directory",
+	list_directory, ls;
+
+request do_stat, "Show inode information ",
+	show_inode_info, stat;
+
+request do_dump_extents, "Dump extents information ",
+	dump_extents, extents, ex;
+
+request do_blocks, "Dump blocks used by an inode ",
+	blocks;
+
+request do_testi, "Test an inode's in-use flag",
+	testi;
+
+request do_find_free_block, "Find free block(s)",
+	find_free_block, ffb;
+
+request do_find_free_inode, "Find free inode(s)",
+	find_free_inode, ffi;
+
+request	do_print_working_directory, "Print current working directory",
+	print_working_directory, pwd; 
+
+request do_lsdel, "List deleted inodes",
+	list_deleted_inodes, lsdel;
+
+request do_logdump, "Dump the contents of the journal",
+	logdump;
+
+request do_htree_dump, "Dump a hash-indexed directory",
+	htree_dump, htree;
+
+request do_dx_hash, "Calculate the directory hash of a filename",
+	dx_hash, hash;
+
+request do_dirsearch, "Search a directory for a particular filename",
+	dirsearch;
+
+request do_bmap, "Calculate the logical->physical block mapping for an inode",
+	bmap;
+
+request do_imap, "Calculate the location of an inode",
+	imap;
+
+request do_supported_features, "Print features supported by this version of e2fsprogs",
+	supported_features;
+
+request do_dump_mmp, "Dump MMP information",
+	dump_mmp;
+
+end;
+
-- 
1.7.4.1.22.gec8e1.dirty


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

* [PATCH] libquota: log an error message if ext2fs_file_open() fails
  2011-11-15  5:05 [PATCH 1/2] debugfs: build read-only variant of debugfs Theodore Ts'o
@ 2011-11-15  5:05 ` Theodore Ts'o
  2011-11-15  5:05 ` [PATCH 2/2] debugfs: add the freefrag command Theodore Ts'o
  2011-11-15 15:41 ` [PATCH 1/2] debugfs: build read-only variant of debugfs Eric Sandeen
  2 siblings, 0 replies; 5+ messages in thread
From: Theodore Ts'o @ 2011-11-15  5:05 UTC (permalink / raw)
  To: Ext4 Developers List; +Cc: Theodore Ts'o

This also fixes a format string type compiler warning.

Signed-off-by: "Theodore Ts'o" <tytso@mit.edu>
---
 lib/quota/quotaio.c |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/lib/quota/quotaio.c b/lib/quota/quotaio.c
index 6edb0b0..d0b5b9d 100644
--- a/lib/quota/quotaio.c
+++ b/lib/quota/quotaio.c
@@ -232,7 +232,7 @@ errcode_t quota_file_open(struct quota_handle *h, ext2_filsys fs,
 	log_debug("Opening quota ino=%lu, type=%d", qf_ino, type);
 	err = ext2fs_file_open(fs, qf_ino, flags, &e2_file);
 	if (err) {
-		log_err("ext2fs_file_open failed: %d", err);
+		log_err("ext2fs_file_open failed: %s", error_message(err));
 		return err;
 	}
 	h->qh_qf.e2_file = e2_file;
-- 
1.7.4.1.22.gec8e1.dirty


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

* [PATCH 2/2] debugfs: add the freefrag command
  2011-11-15  5:05 [PATCH 1/2] debugfs: build read-only variant of debugfs Theodore Ts'o
  2011-11-15  5:05 ` [PATCH] libquota: log an error message if ext2fs_file_open() fails Theodore Ts'o
@ 2011-11-15  5:05 ` Theodore Ts'o
  2011-11-15 15:41 ` [PATCH 1/2] debugfs: build read-only variant of debugfs Eric Sandeen
  2 siblings, 0 replies; 5+ messages in thread
From: Theodore Ts'o @ 2011-11-15  5:05 UTC (permalink / raw)
  To: Ext4 Developers List; +Cc: Theodore Ts'o

The freefrag command provides the functionality of e2freefrag on the
currently open file system in debugfs.

Signed-off-by: "Theodore Ts'o" <tytso@mit.edu>
---
 debugfs/Makefile.in      |    8 ++++-
 debugfs/debug_cmds.ct    |    3 ++
 debugfs/debugfs.8.in     |   10 ++++++
 debugfs/debugfs.h        |    1 +
 debugfs/ro_debug_cmds.ct |    3 ++
 misc/e2freefrag.c        |   74 +++++++++++++++++++++++++++++-----------------
 6 files changed, 70 insertions(+), 29 deletions(-)

diff --git a/debugfs/Makefile.in b/debugfs/Makefile.in
index 4674ba6..e03a3c6 100644
--- a/debugfs/Makefile.in
+++ b/debugfs/Makefile.in
@@ -17,10 +17,10 @@ MANPAGES=	debugfs.8
 MK_CMDS=	_SS_DIR_OVERRIDE=../lib/ss ../lib/ss/mk_cmds
 
 DEBUG_OBJS= debug_cmds.o debugfs.o util.o ncheck.o icheck.o ls.o \
-	lsdel.o dump.o set_fields.o logdump.o htree.o unused.o
+	lsdel.o dump.o set_fields.o logdump.o htree.o unused.o e2freefrag.o
 
 RO_DEBUG_OBJS= ro_debug_cmds.o ro_debugfs.o util.o ncheck.o icheck.o ls.o \
-	lsdel.o logdump.o htree.o
+	lsdel.o logdump.o htree.o e2freefrag.o
 
 SRCS= debug_cmds.c $(srcdir)/debugfs.c $(srcdir)/util.c $(srcdir)/ls.c \
 	$(srcdir)/ncheck.c $(srcdir)/icheck.c $(srcdir)/lsdel.c \
@@ -58,6 +58,10 @@ ro_debugfs.o: debugfs.c
 	$(E) "	CC $@"
 	$(Q) $(CC) -c $(ALL_CFLAGS) $< -DREAD_ONLY -o $@
 
+e2freefrag.o: $(srcdir)/../misc/e2freefrag.c
+	$(E) "	CC $@"
+	$(Q) $(CC) -c $(ALL_CFLAGS) -I$(srcdir) $< -DDEBUGFS -o $@
+
 debugfs.8: $(DEP_SUBSTITUTE) $(srcdir)/debugfs.8.in
 	$(E) "	SUBST $@"
 	$(Q) $(SUBSTITUTE_UPTIME) $(srcdir)/debugfs.8.in debugfs.8
diff --git a/debugfs/debug_cmds.ct b/debugfs/debug_cmds.ct
index ea677da..47de672 100644
--- a/debugfs/debug_cmds.ct
+++ b/debugfs/debug_cmds.ct
@@ -13,6 +13,9 @@ request do_open_filesys, "Open a filesystem",
 request do_close_filesys, "Close the filesystem",
 	close_filesys, close;
 
+request do_freefrag, "Report free space fragmentation",
+	freefrag, e2freefrag;
+
 request do_features, "Set/print superblock features",
 	feature, features;
 
diff --git a/debugfs/debugfs.8.in b/debugfs/debugfs.8.in
index 17ddc24..69490ff 100644
--- a/debugfs/debugfs.8.in
+++ b/debugfs/debugfs.8.in
@@ -280,6 +280,16 @@ blocks starting at block number
 .I block
 will be marked as not allocated.
 .TP
+.I freefrag [-c chunk_kb ]
+Report free space fragmentation on the currently open file system.
+If the
+.I \-c
+option is specified then the filefrag command will print how many free
+chunks of size
+.I chunk_kb
+can be found in the file system.  The chunk size must be a power of two
+and be larger than the file system block size.
+.TP
 .I freei filespec
 Free the inode specified by 
 .IR filespec .
diff --git a/debugfs/debugfs.h b/debugfs/debugfs.h
index 24c4dce..6d7dfcd 100644
--- a/debugfs/debugfs.h
+++ b/debugfs/debugfs.h
@@ -133,3 +133,4 @@ extern void do_set_current_time(int argc, char **argv);
 extern void do_supported_features(int argc, char **argv);
 extern void do_punch(int argc, char **argv);
 
+extern void do_freefrag(int argc, char **argv);
diff --git a/debugfs/ro_debug_cmds.ct b/debugfs/ro_debug_cmds.ct
index 4b16a67..7eb552d 100644
--- a/debugfs/ro_debug_cmds.ct
+++ b/debugfs/ro_debug_cmds.ct
@@ -15,6 +15,9 @@ request do_open_filesys, "Open a filesystem",
 request do_close_filesys, "Close the filesystem",
 	close_filesys, close;
 
+request do_freefrag, "Report free space fragmentation",
+	freefrag, e2freefrag;
+
 request do_show_super_stats, "Show superblock statistics",
 	show_super_stats, stats;
 
diff --git a/misc/e2freefrag.c b/misc/e2freefrag.c
index a09df6b..0964e66 100644
--- a/misc/e2freefrag.c
+++ b/misc/e2freefrag.c
@@ -34,7 +34,9 @@ void usage(const char *prog)
 {
 	fprintf(stderr, "usage: %s [-c chunksize in kb] [-h] "
 		"device_name\n", prog);
+#ifndef DEBUGFS
 	exit(1);
+#endif
 }
 
 static int ul_log2(unsigned long arg)
@@ -140,7 +142,7 @@ void scan_block_bitmap(ext2_filsys fs, struct chunk_info *info)
 		update_chunk_stats(info, last_chunk_size);
 }
 
-errcode_t get_chunk_info(ext2_filsys fs, struct chunk_info *info)
+errcode_t get_chunk_info(ext2_filsys fs, struct chunk_info *info, FILE *f)
 {
 	unsigned long total_chunks;
 	char *unitp = "KMGTPEZY";
@@ -150,20 +152,20 @@ errcode_t get_chunk_info(ext2_filsys fs, struct chunk_info *info)
 
 	scan_block_bitmap(fs, info);
 
-	printf("Total blocks: %llu\nFree blocks: %u (%0.1f%%)\n",
-	       ext2fs_blocks_count(fs->super), fs->super->s_free_blocks_count,
-	       (double)fs->super->s_free_blocks_count * 100 /
-	       ext2fs_blocks_count(fs->super));
+	fprintf(f, "Total blocks: %llu\nFree blocks: %u (%0.1f%%)\n",
+		ext2fs_blocks_count(fs->super), fs->super->s_free_blocks_count,
+		(double)fs->super->s_free_blocks_count * 100 /
+		ext2fs_blocks_count(fs->super));
 
 	if (info->chunkbytes) {
-		printf("\nChunksize: %lu bytes (%u blocks)\n",
-		       info->chunkbytes, info->blks_in_chunk);
+		fprintf(f, "\nChunksize: %lu bytes (%u blocks)\n",
+			info->chunkbytes, info->blks_in_chunk);
 		total_chunks = (ext2fs_blocks_count(fs->super) +
 				info->blks_in_chunk) >>
 			(info->chunkbits - info->blocksize_bits);
-		printf("Total chunks: %lu\nFree chunks: %lu (%0.1f%%)\n",
-		       total_chunks, info->free_chunks,
-		       (double)info->free_chunks * 100 / total_chunks);
+		fprintf(f, "Total chunks: %lu\nFree chunks: %lu (%0.1f%%)\n",
+			total_chunks, info->free_chunks,
+			(double)info->free_chunks * 100 / total_chunks);
 	}
 
 	/* Display chunk information in KB */
@@ -176,13 +178,13 @@ errcode_t get_chunk_info(ext2_filsys fs, struct chunk_info *info)
 		info->min = 0;
 	}
 
-	printf("\nMin. free extent: %lu KB \nMax. free extent: %lu KB\n"
-	       "Avg. free extent: %lu KB\n", info->min, info->max, info->avg);
-	printf("Num. free extent: %lu\n", info->real_free_chunks);
+	fprintf(f, "\nMin. free extent: %lu KB \nMax. free extent: %lu KB\n"
+		"Avg. free extent: %lu KB\n", info->min, info->max, info->avg);
+	fprintf(f, "Num. free extent: %lu\n", info->real_free_chunks);
 
-	printf("\nHISTOGRAM OF FREE EXTENT SIZES:\n");
-	printf("%s :  %12s  %12s  %7s\n", "Extent Size Range", "Free extents",
-	       "Free Blocks", "Percent");
+	fprintf(f, "\nHISTOGRAM OF FREE EXTENT SIZES:\n");
+	fprintf(f, "%s :  %12s  %12s  %7s\n", "Extent Size Range",
+		"Free extents", "Free Blocks", "Percent");
 	for (i = 0; i < MAX_HIST; i++) {
 		end = 1 << (i + info->blocksize_bits - units);
 		if (info->histogram.fc_chunks[i] != 0) {
@@ -191,12 +193,12 @@ errcode_t get_chunk_info(ext2_filsys fs, struct chunk_info *info)
 			sprintf(end_str, "%5lu%c-", end, *unitp);
 			if (i == MAX_HIST-1)
 				strcpy(end_str, "max ");
-			printf("%5lu%c...%7s  :  %12lu  %12lu  %6.2f%%\n",
-			       start, *unitp, end_str,
-			       info->histogram.fc_chunks[i],
-			       info->histogram.fc_blocks[i],
-			       (double)info->histogram.fc_blocks[i] * 100 /
-			       fs->super->s_free_blocks_count);
+			fprintf(f, "%5lu%c...%7s  :  %12lu  %12lu  %6.2f%%\n",
+				start, *unitp, end_str,
+				info->histogram.fc_chunks[i],
+				info->histogram.fc_blocks[i],
+				(double)info->histogram.fc_blocks[i] * 100 /
+				fs->super->s_free_blocks_count);
 		}
 		start = end;
 		if (start == 1<<10) {
@@ -217,12 +219,12 @@ void close_device(char *device_name, ext2_filsys fs)
 		com_err(device_name, retval, "while closing the filesystem.\n");
 }
 
-void collect_info(ext2_filsys fs, struct chunk_info *chunk_info)
+void collect_info(ext2_filsys fs, struct chunk_info *chunk_info, FILE *f)
 {
 	unsigned int retval = 0;
 
-	printf("Device: %s\n", fs->device_name);
-	printf("Blocksize: %u bytes\n", fs->blocksize);
+	fprintf(f, "Device: %s\n", fs->device_name);
+	fprintf(f, "Blocksize: %u bytes\n", fs->blocksize);
 
 	retval = ext2fs_read_block_bitmap(fs);
 	if (retval) {
@@ -233,7 +235,7 @@ void collect_info(ext2_filsys fs, struct chunk_info *chunk_info)
 
 	init_chunk_info(fs, chunk_info);
 
-	retval = get_chunk_info(fs, chunk_info);
+	retval = get_chunk_info(fs, chunk_info, f);
 	if (retval) {
 		com_err(fs->device_name, retval, "while collecting chunk info");
                 close_device(fs->device_name, fs);
@@ -253,7 +255,14 @@ void open_device(char *device_name, ext2_filsys *fs)
 	}
 }
 
+#ifdef DEBUGFS
+
+#include "debugfs.h"
+
+void do_freefrag(int argc, char **argv)
+#else
 int main(int argc, char *argv[])
+#endif
 {
 	struct chunk_info chunk_info = { };
 	errcode_t retval = 0;
@@ -263,7 +272,12 @@ int main(int argc, char *argv[])
 	char *end;
 	int c;
 
+#ifdef DEBUGFS
+	if (check_fs_open(argv[0]))
+		return;
+#else
 	add_error_table(&et_ext2_error_table);
+#endif
 	progname = argv[0];
 
 	while ((c = getopt(argc, argv, "c:h")) != EOF) {
@@ -290,6 +304,7 @@ int main(int argc, char *argv[])
 		}
 	}
 
+#ifndef DEBUGFS
 	if (optind == argc) {
 		fprintf(stderr, "%s: missing device name.\n", progname);
 		usage(progname);
@@ -298,14 +313,19 @@ int main(int argc, char *argv[])
 	device_name = argv[optind];
 
 	open_device(device_name, &fs);
+#else
+	fs = current_fs;
+#endif
 
 	if (chunk_info.chunkbytes && (chunk_info.chunkbytes < fs->blocksize)) {
 		fprintf(stderr, "%s: chunksize must be greater than or equal "
 			"to filesystem blocksize.\n", progname);
 		exit(1);
 	}
-	collect_info(fs, &chunk_info);
+	collect_info(fs, &chunk_info, stdout);
+#ifndef DEBUGFS
 	close_device(device_name, fs);
 
 	return retval;
+#endif
 }
-- 
1.7.4.1.22.gec8e1.dirty


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

* Re: [PATCH 1/2] debugfs: build read-only variant of debugfs
  2011-11-15  5:05 [PATCH 1/2] debugfs: build read-only variant of debugfs Theodore Ts'o
  2011-11-15  5:05 ` [PATCH] libquota: log an error message if ext2fs_file_open() fails Theodore Ts'o
  2011-11-15  5:05 ` [PATCH 2/2] debugfs: add the freefrag command Theodore Ts'o
@ 2011-11-15 15:41 ` Eric Sandeen
  2011-11-17 21:11   ` Ted Ts'o
  2 siblings, 1 reply; 5+ messages in thread
From: Eric Sandeen @ 2011-11-15 15:41 UTC (permalink / raw)
  To: Theodore Ts'o; +Cc: Ext4 Developers List

-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

On 11/14/11 11:05 PM, Theodore Ts'o wrote:
> Create a version of debugfs which only supports read-only examination
> of the file system metadata (but not the data blocks).  The idea is
> that this version of debugfs might be suitable to be setuid root, and
> executable only by members of a particular group, or setgid disk, and
> globally executable, depending on the security/privacy policies in
> force at a particular site.

Just curious - what problem does this solve?

(Could the same policies simply make direct access to block devices
read-only for those users, and thus have an fs-independent solution
to whatever problem is at hand?)

- -Eric

> Signed-off-by: "Theodore Ts'o" <tytso@mit.edu>
> ---
>  debugfs/Makefile.in      |   20 ++++++++++-
>  debugfs/debugfs.c        |   53 ++++++++++++++++++++++++++---
>  debugfs/ro_debug_cmds.ct |   85 ++++++++++++++++++++++++++++++++++++++++++++++
>  3 files changed, 151 insertions(+), 7 deletions(-)
>  create mode 100644 debugfs/ro_debug_cmds.ct
> 
> diff --git a/debugfs/Makefile.in b/debugfs/Makefile.in
> index e314b91..4674ba6 100644
> --- a/debugfs/Makefile.in
> +++ b/debugfs/Makefile.in
> @@ -11,7 +11,7 @@ INSTALL = @INSTALL@
>  
>  @MCONFIG@
>  
> -PROGS=		debugfs
> +PROGS=		debugfs rdebugfs
>  MANPAGES=	debugfs.8
>  
>  MK_CMDS=	_SS_DIR_OVERRIDE=../lib/ss ../lib/ss/mk_cmds
> @@ -19,6 +19,9 @@ MK_CMDS=	_SS_DIR_OVERRIDE=../lib/ss ../lib/ss/mk_cmds
>  DEBUG_OBJS= debug_cmds.o debugfs.o util.o ncheck.o icheck.o ls.o \
>  	lsdel.o dump.o set_fields.o logdump.o htree.o unused.o
>  
> +RO_DEBUG_OBJS= ro_debug_cmds.o ro_debugfs.o util.o ncheck.o icheck.o ls.o \
> +	lsdel.o logdump.o htree.o
> +
>  SRCS= debug_cmds.c $(srcdir)/debugfs.c $(srcdir)/util.c $(srcdir)/ls.c \
>  	$(srcdir)/ncheck.c $(srcdir)/icheck.c $(srcdir)/lsdel.c \
>  	$(srcdir)/dump.c $(srcdir)/set_fields.c ${srcdir}/logdump.c \
> @@ -39,10 +42,22 @@ debugfs: $(DEBUG_OBJS) $(DEPLIBS)
>  	$(E) "	LD $@"
>  	$(Q) $(CC) $(ALL_LDFLAGS) -o debugfs $(DEBUG_OBJS) $(LIBS)
>  
> +rdebugfs: $(RO_DEBUG_OBJS) $(DEPLIBS)
> +	$(E) "	LD $@"
> +	$(Q) $(CC) $(ALL_LDFLAGS) -o rdebugfs $(RO_DEBUG_OBJS) $(LIBS)
> +
>  debug_cmds.c debug_cmds.h: debug_cmds.ct
>  	$(E) "	MK_CMDS $@"
>  	$(Q) $(MK_CMDS) $(srcdir)/debug_cmds.ct
>  
> +ro_debug_cmds.c ro_debug_cmds.h: ro_debug_cmds.ct
> +	$(E) "	MK_CMDS $@"
> +	$(Q) $(MK_CMDS) $(srcdir)/ro_debug_cmds.ct
> +
> +ro_debugfs.o: debugfs.c
> +	$(E) "	CC $@"
> +	$(Q) $(CC) -c $(ALL_CFLAGS) $< -DREAD_ONLY -o $@
> +
>  debugfs.8: $(DEP_SUBSTITUTE) $(srcdir)/debugfs.8.in
>  	$(E) "	SUBST $@"
>  	$(Q) $(SUBSTITUTE_UPTIME) $(srcdir)/debugfs.8.in debugfs.8
> @@ -80,7 +95,8 @@ uninstall:
>  	done
>  
>  clean:
> -	$(RM) -f debugfs debugfs.8 \#* *.s *.o *.a *~ debug_cmds.c core
> +	$(RM) -f $(PROGS) debugfs.8 \#* *.s *.o *.a *~ debug_cmds.c \
> +		ro_debug_cmds.c core
>  
>  mostlyclean: clean
>  distclean: clean
> diff --git a/debugfs/debugfs.c b/debugfs/debugfs.c
> index 1fb8f44..fda8d92 100644
> --- a/debugfs/debugfs.c
> +++ b/debugfs/debugfs.c
> @@ -140,7 +140,11 @@ void do_open_filesys(int argc, char **argv)
>  			open_flags |= EXT2_FLAG_IMAGE_FILE;
>  			break;
>  		case 'w':
> +#ifdef READ_ONLY
> +			goto print_usage;
> +#else
>  			open_flags |= EXT2_FLAG_RW;
> +#endif /* READ_ONLY */
>  			break;
>  		case 'f':
>  			open_flags |= EXT2_FLAG_FORCE;
> @@ -184,8 +188,11 @@ void do_open_filesys(int argc, char **argv)
>  	return;
>  
>  print_usage:
> -	fprintf(stderr, "%s: Usage: open [-s superblock] [-b blocksize] "
> -		"[-c] [-w] <device>\n", argv[0]);
> +	fprintf(stderr, "%s: Usage: open [-s superblock] [-b blocksize] [-c] "
> +#ifndef READ_ONLY
> +		"[-w] "
> +#endif
> +		"<device>\n", argv[0]);
>  }
>  
>  void do_lcd(int argc, char **argv)
> @@ -251,6 +258,7 @@ void do_close_filesys(int argc, char **argv)
>  	close_filesystem();
>  }
>  
> +#ifndef READ_ONLY
>  void do_init_filesys(int argc, char **argv)
>  {
>  	struct ext2_super_block param;
> @@ -276,6 +284,7 @@ void do_init_filesys(int argc, char **argv)
>  	root = cwd = EXT2_ROOT_INO;
>  	return;
>  }
> +#endif /* READ_ONLY */
>  
>  static void print_features(struct ext2_super_block * s, FILE *f)
>  {
> @@ -393,6 +402,7 @@ print_usage:
>  	fprintf(stderr, "%s: Usage: show_super [-h]\n", argv[0]);
>  }
>  
> +#ifndef READ_ONLY
>  void do_dirty_filesys(int argc EXT2FS_ATTR((unused)),
>  		      char **argv EXT2FS_ATTR((unused)))
>  {
> @@ -407,6 +417,7 @@ void do_dirty_filesys(int argc EXT2FS_ATTR((unused)),
>  		current_fs->super->s_state &= ~EXT2_VALID_FS;
>  	ext2fs_mark_super_dirty(current_fs);
>  }
> +#endif /* READ_ONLY */
>  
>  struct list_blocks_struct {
>  	FILE		*f;
> @@ -964,6 +975,7 @@ void do_chroot(int argc, char *argv[])
>  	root = inode;
>  }
>  
> +#ifndef READ_ONLY
>  void do_clri(int argc, char *argv[])
>  {
>  	ext2_ino_t inode;
> @@ -1006,6 +1018,7 @@ void do_seti(int argc, char *argv[])
>  	ext2fs_mark_inode_bitmap2(current_fs->inode_map,inode);
>  	ext2fs_mark_ib_dirty(current_fs);
>  }
> +#endif /* READ_ONLY */
>  
>  void do_testi(int argc, char *argv[])
>  {
> @@ -1020,6 +1033,7 @@ void do_testi(int argc, char *argv[])
>  		printf("Inode %u is not in use\n", inode);
>  }
>  
> +#ifndef READ_ONLY
>  void do_freeb(int argc, char *argv[])
>  {
>  	blk64_t block;
> @@ -1057,6 +1071,7 @@ void do_setb(int argc, char *argv[])
>  	}
>  	ext2fs_mark_bb_dirty(current_fs);
>  }
> +#endif /* READ_ONLY */
>  
>  void do_testb(int argc, char *argv[])
>  {
> @@ -1074,6 +1089,7 @@ void do_testb(int argc, char *argv[])
>  	}
>  }
>  
> +#ifndef READ_ONLY
>  static void modify_u8(char *com, const char *prompt,
>  		      const char *format, __u8 *val)
>  {
> @@ -1217,6 +1233,7 @@ void do_modify_inode(int argc, char *argv[])
>  	if (debugfs_write_inode(inode_num, &inode, argv[1]))
>  		return;
>  }
> +#endif /* READ_ONLY */
>  
>  void do_change_working_dir(int argc, char *argv[])
>  {
> @@ -1298,6 +1315,7 @@ static int ext2_file_type(unsigned int mode)
>  	return 0;
>  }
>  
> +#ifndef READ_ONLY
>  static void make_link(char *sourcename, char *destname)
>  {
>  	ext2_ino_t	ino;
> @@ -1445,6 +1463,7 @@ void do_unlink(int argc, char *argv[])
>  
>  	unlink_file_by_name(argv[1]);
>  }
> +#endif /* READ_ONLY */
>  
>  void do_find_free_block(int argc, char *argv[])
>  {
> @@ -1537,6 +1556,7 @@ void do_find_free_inode(int argc, char *argv[])
>  		printf("Free inode found: %u\n", free_inode);
>  }
>  
> +#ifndef READ_ONLY
>  static errcode_t copy_file(int fd, ext2_ino_t newfile)
>  {
>  	ext2_file_t	e2_file;
> @@ -1944,6 +1964,7 @@ void do_rmdir(int argc, char *argv[])
>  			return;
>  	}
>  }
> +#endif /* READ_ONLY */
>  
>  void do_show_debugfs_params(int argc EXT2FS_ATTR((unused)),
>  			    char *argv[] EXT2FS_ATTR((unused)))
> @@ -1957,6 +1978,7 @@ void do_show_debugfs_params(int argc EXT2FS_ATTR((unused)),
>  		current_fs ? current_fs->device_name : "--none--");
>  }
>  
> +#ifndef READ_ONLY
>  void do_expand_dir(int argc, char *argv[])
>  {
>  	ext2_ino_t inode;
> @@ -1990,6 +2012,7 @@ void do_features(int argc, char *argv[])
>  	}
>  	print_features(current_fs->super, stdout);
>  }
> +#endif /* READ_ONLY */
>  
>  void do_bmap(int argc, char *argv[])
>  {
> @@ -2047,6 +2070,7 @@ void do_imap(int argc, char *argv[])
>  
>  }
>  
> +#ifndef READ_ONLY
>  void do_set_current_time(int argc, char *argv[])
>  {
>  	time_t now;
> @@ -2066,6 +2090,7 @@ void do_set_current_time(int argc, char *argv[])
>  		current_fs->now = now;
>  	}
>  }
> +#endif /* READ_ONLY */
>  
>  static int find_supp_feature(__u32 *supp, int feature_type, char *name)
>  {
> @@ -2132,6 +2157,7 @@ void do_supported_features(int argc, char *argv[])
>  	}
>  }
>  
> +#ifndef READ_ONLY
>  void do_punch(int argc, char *argv[])
>  {
>  	ext2_ino_t	ino;
> @@ -2162,6 +2188,7 @@ void do_punch(int argc, char *argv[])
>  		return;
>  	}
>  }
> +#endif /* READ_ONLY */
>  
>  void do_dump_mmp(int argc, char *argv[])
>  {
> @@ -2256,7 +2283,13 @@ int main(int argc, char **argv)
>  {
>  	int		retval;
>  	int		sci_idx;
> -	const char	*usage = "Usage: %s [-b blocksize] [-s superblock] [-f cmd_file] [-R request] [-V] [[-w] [-c] device]";
> +	const char	*usage = 
> +		"Usage: %s [-b blocksize] [-s superblock] [-f cmd_file] "
> +		"[-R request] [-V] ["
> +#ifndef READ_ONLY
> +		"[-w] "
> +#endif
> +		"[-c] device]";
>  	int		c;
>  	int		open_flags = EXT2_FLAG_SOFTSUPP_FEATURES | EXT2_FLAG_64BITS;
>  	char		*request = 0;
> @@ -2266,15 +2299,23 @@ int main(int argc, char **argv)
>  	blk64_t		blocksize = 0;
>  	int		catastrophic = 0;
>  	char		*data_filename = 0;
> +#ifdef READ_ONLY
> +	const char	*opt_string = "iwcR:f:b:s:Vd:D";
> +#else
> +	const char	*opt_string = "icR:f:b:s:Vd:D";
> +#endif
>  
>  	if (debug_prog_name == 0)
> +#ifdef READ_ONLY
> +		debug_prog_name = "rdebugfs";
> +#else
>  		debug_prog_name = "debugfs";
> -
> +#endif
>  	add_error_table(&et_ext2_error_table);
>  	fprintf (stderr, "%s %s (%s)\n", debug_prog_name,
>  		 E2FSPROGS_VERSION, E2FSPROGS_DATE);
>  
> -	while ((c = getopt (argc, argv, "iwcR:f:b:s:Vd:D")) != EOF) {
> +	while ((c = getopt (argc, argv, opt_string)) != EOF) {
>  		switch (c) {
>  		case 'R':
>  			request = optarg;
> @@ -2288,9 +2329,11 @@ int main(int argc, char **argv)
>  		case 'i':
>  			open_flags |= EXT2_FLAG_IMAGE_FILE;
>  			break;
> +#ifndef READ_ONLY
>  		case 'w':
>  			open_flags |= EXT2_FLAG_RW;
>  			break;
> +#endif
>  		case 'D':
>  			open_flags |= EXT2_FLAG_DIRECT_IO;
>  			break;
> diff --git a/debugfs/ro_debug_cmds.ct b/debugfs/ro_debug_cmds.ct
> new file mode 100644
> index 0000000..4b16a67
> --- /dev/null
> +++ b/debugfs/ro_debug_cmds.ct
> @@ -0,0 +1,85 @@
> +#
> +# Restricted set of debugfs commands
> +#
> +# Copyright (C) 1993 Theodore Ts'o.  This file may be redistributed
> +# under the terms of the GNU Public License.
> +#
> +command_table debug_cmds;
> +
> +request do_show_debugfs_params, "Show debugfs parameters",
> +	show_debugfs_params, params;
> +
> +request do_open_filesys, "Open a filesystem",
> +	open_filesys, open;
> +
> +request do_close_filesys, "Close the filesystem",
> +	close_filesys, close;
> +
> +request do_show_super_stats, "Show superblock statistics",
> +	show_super_stats, stats;
> +
> +request do_ncheck, "Do inode->name translation",
> +	ncheck;
> +
> +request do_icheck, "Do block->inode translation",
> +	icheck;
> +
> +request do_chroot, "Change root directory",
> +	change_root_directory, chroot;
> +
> +request do_change_working_dir, "Change working directory",
> +	change_working_directory, cd;
> +
> +request do_list_dir, "List directory",
> +	list_directory, ls;
> +
> +request do_stat, "Show inode information ",
> +	show_inode_info, stat;
> +
> +request do_dump_extents, "Dump extents information ",
> +	dump_extents, extents, ex;
> +
> +request do_blocks, "Dump blocks used by an inode ",
> +	blocks;
> +
> +request do_testi, "Test an inode's in-use flag",
> +	testi;
> +
> +request do_find_free_block, "Find free block(s)",
> +	find_free_block, ffb;
> +
> +request do_find_free_inode, "Find free inode(s)",
> +	find_free_inode, ffi;
> +
> +request	do_print_working_directory, "Print current working directory",
> +	print_working_directory, pwd; 
> +
> +request do_lsdel, "List deleted inodes",
> +	list_deleted_inodes, lsdel;
> +
> +request do_logdump, "Dump the contents of the journal",
> +	logdump;
> +
> +request do_htree_dump, "Dump a hash-indexed directory",
> +	htree_dump, htree;
> +
> +request do_dx_hash, "Calculate the directory hash of a filename",
> +	dx_hash, hash;
> +
> +request do_dirsearch, "Search a directory for a particular filename",
> +	dirsearch;
> +
> +request do_bmap, "Calculate the logical->physical block mapping for an inode",
> +	bmap;
> +
> +request do_imap, "Calculate the location of an inode",
> +	imap;
> +
> +request do_supported_features, "Print features supported by this version of e2fsprogs",
> +	supported_features;
> +
> +request do_dump_mmp, "Dump MMP information",
> +	dump_mmp;
> +
> +end;
> +

-----BEGIN PGP SIGNATURE-----
Version: GnuPG/MacGPG2 v2.0.17 (Darwin)
Comment: GPGTools - http://gpgtools.org
Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org/

iQIcBAEBAgAGBQJOwohEAAoJECCuFpLhPd7gzEUQAISFIzFo1U2Tx0xsIJWCLzuS
/mYVLTq2I4MvwQ87HQvMEl+cb6EdHCFm5VSVRGcMN2qd/jCvN8DW7XiwxA5JJvrv
nXmqcp4HMOCOe1fzmRl5Q+GMoJQpNAbgBcVne0l9QJJxO3xbteDBoPrR7jRyHq7V
38kfXa87/MVxm5Q3u6dldHeyU4xKJwIoyQ31bOcnKl8pdJP9sJvVyqvr4zJMkZb+
UnXYcXWAJEBoVChOYBmc8BlHOBvQwecS47XM05TVcY5TYh5VtPoxC2lZKbH8HCFV
k6AEExieGUisOZ5S5+OctS+5syFaoiZMVnbSN9EQd44WxhDGKh77cG+mTRc9kUBr
lbLZvGhnpdcinzT7SiCSGO5MPtnr3UNThZSR29rW2kIZOOJLJKLP/+FobCWhLJOt
LCa4T+OVaFxNk0QBFyK7/m1ARAWDBPs2kiC5sL07kSyqwIGqVy2hbot4OyRgVPzM
4FZIrOo0FGA7p5LXqrlGz88AavCFRo/VNWv8LPfP/VNDTgJlXIGc9g/rwRFhrQum
657OOriFP9V2bw4uG3/Mxl8GYQgCmlEnEn4LUEIO0nl9UU69xEbWaR5jlpr3IWyx
AfQWG1WEo5lRUTqFGlLQ8qEYZs6LoIyjR3987uWrI5W7A7PAKlik7d3V3YkK5gtY
njKXQkCkmA/ijW60FsED
=SVNC
-----END PGP SIGNATURE-----

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

* Re: [PATCH 1/2] debugfs: build read-only variant of debugfs
  2011-11-15 15:41 ` [PATCH 1/2] debugfs: build read-only variant of debugfs Eric Sandeen
@ 2011-11-17 21:11   ` Ted Ts'o
  0 siblings, 0 replies; 5+ messages in thread
From: Ted Ts'o @ 2011-11-17 21:11 UTC (permalink / raw)
  To: Eric Sandeen; +Cc: Ext4 Developers List

On Tue, Nov 15, 2011 at 09:41:57AM -0600, Eric Sandeen wrote:
> On 11/14/11 11:05 PM, Theodore Ts'o wrote:
> > Create a version of debugfs which only supports read-only examination
> > of the file system metadata (but not the data blocks).  The idea is
> > that this version of debugfs might be suitable to be setuid root, and
> > executable only by members of a particular group, or setgid disk, and
> > globally executable, depending on the security/privacy policies in
> > force at a particular site.
> 
> Just curious - what problem does this solve?
> 
> (Could the same policies simply make direct access to block devices
> read-only for those users, and thus have an fs-independent solution
> to whatever problem is at hand?)

It's not enough to make access to the block devices be read-only;
what's most important in this patch is removing the ability to show
data blocks (i.e., removing the debugfs "cat" and "dump" commands).
After all, a company with very strict user data privacy policies might
require a developer to jump through hoops before getting access which
allowed him or her to bypass file system access controls, whether it
is logging in as root or installing some setuid/setgid binary which
had the effect of bypassing mandatory or discretionary access controls
--- which debugfs's "dump" and "cat" commands effectively do.

There's another reason for removing all of the commands that might be
used to modify file system metadata, as well as forcing the block
device to be opened read-only.  It makes it easier for a
security/privacy committee who might want to audit the code to make
sure no one can use the restricted version of debugfs to flip a setuid
bit, or change a file's permissions, or some other entertaining file
system modification.

I could also imagine this sort of thing could also being useful for
advanced support personnel who need to go on site (say, at a financial
institution in NYC) and who needs to debug a customer's file system or
investigate a performance problem.

						- Ted

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

end of thread, other threads:[~2011-11-17 21:11 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2011-11-15  5:05 [PATCH 1/2] debugfs: build read-only variant of debugfs Theodore Ts'o
2011-11-15  5:05 ` [PATCH] libquota: log an error message if ext2fs_file_open() fails Theodore Ts'o
2011-11-15  5:05 ` [PATCH 2/2] debugfs: add the freefrag command Theodore Ts'o
2011-11-15 15:41 ` [PATCH 1/2] debugfs: build read-only variant of debugfs Eric Sandeen
2011-11-17 21:11   ` Ted Ts'o

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).