diff mbox series

fstools: blockd Check /tmp/run/blockd for existing mounts

Message ID mailman.3801.1623121751.434944.openwrt-devel@lists.openwrt.org
State New
Headers show
Series fstools: blockd Check /tmp/run/blockd for existing mounts | expand

Commit Message

David Adair June 8, 2021, 3:09 a.m. UTC
The sender domain has a DMARC Reject/Quarantine policy which disallows
sending mailing list messages using the original "From" header.

To mitigate this problem, the original message has been wrapped
automatically by the mailing list software.
Currently volume names can not match rootfs files/directories
so names like "home" "usr" or "www" are not allowed.

This changes the check for existing mount points to
examine /tmp/run/blockd/<newdev> instead of /<newdev>.

It also checks that a link is present at
/mnt/<newdev> and skips the request if it is missing
e.g. the "map" does not support the requested "key".

This aligns the mount logic to match the automount
daemon indirect.c logic from kernel.org.
 - If mountpoint exist and is not a zombie return success.
 - If mountpoint is a zombie delete it.
 - If map is missing or mount fails return failure.

This greatly simplifies hotplug-remove since we leave
devices alone once link is removed.  It also fixes most
instances of poision directories remaining in automount
dir and causing "too many symlinks" errors.

Signed-off-by: David Adair <djabhead@aol.com>
---
 blockd.c | 23 ++++++++++++++++++++---
 1 file changed, 20 insertions(+), 3 deletions(-)

                if (errno != EINTR)
@@ -517,9 +519,23 @@ static void autofs_read_handler(struct uloop_fd *u, unsigned int
events)
 
        pkt = &pktu.missing_indirect;
         ULOG_ERR("kernel is requesting a mount -> %s\n", pkt->name);
-       if (lstat(pkt->name, &st) == -1)
-               if (block("autofs", "add", (char *)pkt->name))
-                       cmd = AUTOFS_IOC_FAIL;
+       /*
+        * if MP exists send "ready"
+        *   second part of check detects zombie mounts --
+        *   valid target should have target dev.
+        */
+       if (asprintf(&mnt, "%s%s", AUTOFS_MOUNT_PATH, pkt->name) == -1)
+               exit(ENOMEM);
+       if ((lstat(mnt, &st) == -1) ||
+           (S_ISDIR(st.st_mode) && st.st_dev == autofs_mp_stat.st_dev)) {
+               rmdir(mnt);
+               sprintf(mnt, "/mnt/%s", pkt->name);
+               /* Map doesn't exist or mount fails send "fail" */
+               if (lstat(mnt, &st) || ! S_ISLNK(st.st_mode) ||
+                   block("autofs", "add", (char *)pkt->name))
+                               cmd = AUTOFS_IOC_FAIL;
+       }
+       free(mnt);
 
        if (ioctl(fd_autofs_write, cmd, pkt->wait_queue_token) < 0)
                ULOG_ERR("failed to report back to kernel\n");
@@ -562,6 +578,7 @@ static int autofs_mount(void)
                return -1;
        }
        close(pipefd[1]);
+       stat(AUTOFS_MOUNT_PATH, &autofs_mp_stat);
        fd_autofs_read.fd = pipefd[0];
        fd_autofs_read.cb = autofs_read_handler;
        uloop_fd_add(&fd_autofs_read, ULOOP_READ);
diff mbox series

Patch

diff --git a/blockd.c b/blockd.c
index d6dfeb8..eacea27 100644
--- a/blockd.c
+++ b/blockd.c
@@ -41,6 +41,7 @@  struct device {
 
 static struct uloop_fd fd_autofs_read;
 static int fd_autofs_write = 0;
+static struct stat autofs_mp_stat;
 static struct ubus_auto_conn conn;
 struct blob_buf bb = { 0 };
 
@@ -503,6 +504,7 @@  static void autofs_read_handler(struct uloop_fd *u, unsigned int
events)
        const struct autofs_v5_packet *pkt;
        int cmd = AUTOFS_IOC_READY;
        struct stat st;
+       char *mnt;
 
        while (read(u->fd, &pktu, sizeof(pktu)) == -1) {