]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
afs: Fix the maximum cell name length
authorDavid Howells <dhowells@redhat.com>
Mon, 6 Jan 2025 16:21:00 +0000 (16:21 +0000)
committerChristian Brauner <brauner@kernel.org>
Tue, 7 Jan 2025 14:55:25 +0000 (15:55 +0100)
The kafs filesystem limits the maximum length of a cell to 256 bytes, but a
problem occurs if someone actually does that: kafs tries to create a
directory under /proc/net/afs/ with the name of the cell, but that fails
with a warning:

        WARNING: CPU: 0 PID: 9 at fs/proc/generic.c:405

because procfs limits the maximum filename length to 255.

However, the DNS limits the maximum lookup length and, by extension, the
maximum cell name, to 255 less two (length count and trailing NUL).

Fix this by limiting the maximum acceptable cellname length to 253.  This
also allows us to be sure we can create the "/afs/.<cell>/" mountpoint too.

Further, split the YFS VL record cell name maximum to be the 256 allowed by
the protocol and ignore the record retrieved by YFSVL.GetCellName if it
exceeds 253.

Fixes: c3e9f888263b ("afs: Implement client support for the YFSVL.GetCellName RPC op")
Reported-by: syzbot+7848fee1f1e5c53f912b@syzkaller.appspotmail.com
Closes: https://lore.kernel.org/r/6776d25d.050a0220.3a8527.0048.GAE@google.com/
Signed-off-by: David Howells <dhowells@redhat.com>
Link: https://lore.kernel.org/r/376236.1736180460@warthog.procyon.org.uk
Tested-by: syzbot+7848fee1f1e5c53f912b@syzkaller.appspotmail.com
cc: Marc Dionne <marc.dionne@auristor.com>
cc: linux-afs@lists.infradead.org
Signed-off-by: Christian Brauner <brauner@kernel.org>
fs/afs/afs.h
fs/afs/afs_vl.h
fs/afs/vl_alias.c
fs/afs/vlclient.c

index b488072aee87ae45847b9c162aa86ee3c4dba239..ec3db00bd0813cf6646e11834dab1a314fd949f7 100644 (file)
@@ -10,7 +10,7 @@
 
 #include <linux/in.h>
 
-#define AFS_MAXCELLNAME                256     /* Maximum length of a cell name */
+#define AFS_MAXCELLNAME                253     /* Maximum length of a cell name (DNS limited) */
 #define AFS_MAXVOLNAME         64      /* Maximum length of a volume name */
 #define AFS_MAXNSERVERS                8       /* Maximum servers in a basic volume record */
 #define AFS_NMAXNSERVERS       13      /* Maximum servers in a N/U-class volume record */
index a06296c8827d42e9ce78f04c49365a220c584c86..b835e25a2c02d3f9f7d8ef319cd23284e4be5493 100644 (file)
@@ -13,6 +13,7 @@
 #define AFS_VL_PORT            7003    /* volume location service port */
 #define VL_SERVICE             52      /* RxRPC service ID for the Volume Location service */
 #define YFS_VL_SERVICE         2503    /* Service ID for AuriStor upgraded VL service */
+#define YFS_VL_MAXCELLNAME     256     /* Maximum length of a cell name in YFS protocol */
 
 enum AFSVL_Operations {
        VLGETENTRYBYID          = 503,  /* AFS Get VLDB entry by ID */
index 9f36e14f1c2d24919b53f78232b4556f79a54b66..f9e76b604f31b9a3379b452327493706f81d58cc 100644 (file)
@@ -253,6 +253,7 @@ static char *afs_vl_get_cell_name(struct afs_cell *cell, struct key *key)
 static int yfs_check_canonical_cell_name(struct afs_cell *cell, struct key *key)
 {
        struct afs_cell *master;
+       size_t name_len;
        char *cell_name;
 
        cell_name = afs_vl_get_cell_name(cell, key);
@@ -264,8 +265,11 @@ static int yfs_check_canonical_cell_name(struct afs_cell *cell, struct key *key)
                return 0;
        }
 
-       master = afs_lookup_cell(cell->net, cell_name, strlen(cell_name),
-                                NULL, false);
+       name_len = strlen(cell_name);
+       if (!name_len || name_len > AFS_MAXCELLNAME)
+               master = ERR_PTR(-EOPNOTSUPP);
+       else
+               master = afs_lookup_cell(cell->net, cell_name, name_len, NULL, false);
        kfree(cell_name);
        if (IS_ERR(master))
                return PTR_ERR(master);
index cac75f89b64ad1ccbdf4cd0a66875093f437f34e..55dd0fc5aad7bf70783dbbc4dace705096b7ed33 100644 (file)
@@ -697,7 +697,7 @@ static int afs_deliver_yfsvl_get_cell_name(struct afs_call *call)
                        return ret;
 
                namesz = ntohl(call->tmp);
-               if (namesz > AFS_MAXCELLNAME)
+               if (namesz > YFS_VL_MAXCELLNAME)
                        return afs_protocol_error(call, afs_eproto_cellname_len);
                paddedsz = (namesz + 3) & ~3;
                call->count = namesz;