From 0033d20449b3bb558f2ea470983018db39b572aa Mon Sep 17 00:00:00 2001 From: Justus Winter <4winter@informatik.uni-hamburg.de> Date: Sun, 12 Jan 2014 15:05:53 +0100 Subject: trans/mtab: do not include non-filesystem translators by default Traditionally, /proc/mounts includes only filesystem mount points. Previously though, the mtab translator included any kind of translator, like all /hurd/storeio translators. This causes problems with umount --all as this would remove the passive translator records from nodes in /dev. Fix this by only listing filesystem-like translators by default. Filesystem-like translators are identified by their response to dir_readdir messages sent to their root node. * trans/mtab.c (all_translators): New variable. (options): Add flag to preserve the old behavior. (parse_opt): Handle the new flag. (is_filesystem_translator): New function. (mtab_populate): Skip non-filesystem translators by default. --- trans/mtab.c | 40 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 40 insertions(+) (limited to 'trans') diff --git a/trans/mtab.c b/trans/mtab.c index adfb3458..75ef1d3a 100644 --- a/trans/mtab.c +++ b/trans/mtab.c @@ -40,6 +40,7 @@ static char *target_path = NULL; static int insecure = 0; +static int all_translators = 0; /* Our control port. */ struct trivfs_control *control; @@ -60,6 +61,9 @@ static const struct argp_option options[] = { {"insecure", 'I', 0, 0, "Follow translators not bound to nodes owned by you or root"}, + {"all-translators", 'A', 0, 0, + "List all translators, even those that are probably not " + "filesystem translators"}, {} }; @@ -72,6 +76,10 @@ error_t parse_opt (int key, char *arg, struct argp_state *state) insecure = 1; break; + case 'A': + all_translators = 1; + break; + case ARGP_KEY_ARG: target_path = realpath (arg, NULL); if (! target_path) @@ -277,6 +285,32 @@ mtab_add_entry (struct mtab *mtab, const char *entry, size_t length) return 0; } +/* Check whether the given NODE is a directory on a filesystem + translator. */ +static boolean_t +is_filesystem_translator (file_t node) +{ + error_t err; + char *data = NULL; + size_t datacnt = 0; + int amount; + err = dir_readdir (node, &data, &datacnt, 0, 1, 0, &amount); + if (data != NULL && datacnt > 0) + vm_deallocate (mach_task_self (), (vm_address_t) data, datacnt); + + /* Filesystem translators return either no error, or, if NODE has + not been looked up with O_READ, EBADF to dir_readdir + requests. */ + switch (err) + { + case 0: + case EBADF: + return TRUE; + default: + return FALSE; + } +} + /* Populates the given MTAB object with the information for PATH. If INSECURE is given, also follow translators bound to nodes not owned by root or the current user. */ @@ -333,6 +367,12 @@ mtab_populate (struct mtab *mtab, const char *path, int insecure) goto errout; } + if (! (all_translators || is_filesystem_translator (node))) + { + err = 0; + goto errout; + } + /* Query its options. */ err = file_get_fs_options (node, &argz, &argz_len); if (err) -- cgit v1.2.3