smbd: Remove "unparsed" from struct open_symlink_err
authorVolker Lendecke <vl@samba.org>
Sun, 4 Feb 2024 16:42:28 +0000 (17:42 +0100)
committerAndreas Schneider <asn@cryptomilk.org>
Thu, 28 Mar 2024 08:05:35 +0000 (08:05 +0000)
We have the reserved field unparsed_path_length as part of struct
symlink_reparse_struct.

Signed-off-by: Volker Lendecke <vl@samba.org>
Reviewed-by: Andreas Schneider <asn@samba.org>
source3/smbd/filename.c
source3/smbd/files.c
source3/smbd/proto.h

index b542d2fcf6f5f59e62a7b9f4658d88a726b97fdf..92194a371433ac4b8f828bacb3678c4eedcee0c5 100644 (file)
@@ -846,6 +846,9 @@ static NTSTATUS filename_convert_dirfsp_nosymlink(
                                                      &symlink_err);
 
                if (NT_STATUS_EQUAL(status, NT_STATUS_STOPPED_ON_SYMLINK)) {
+                       struct symlink_reparse_struct
+                               *lnk = &symlink_err->reparse->parsed.lnk;
+                       size_t unparsed = lnk->unparsed_path_length;
                        size_t name_in_len, dirname_len;
 
                        name_in_len = strlen(name_in);
@@ -853,7 +856,14 @@ static NTSTATUS filename_convert_dirfsp_nosymlink(
 
                        SMB_ASSERT(name_in_len >= dirname_len);
 
-                       symlink_err->unparsed += (name_in_len - dirname_len);
+                       unparsed += (name_in_len - dirname_len);
+
+                       if (unparsed > UINT16_MAX) {
+                               status = NT_STATUS_BUFFER_OVERFLOW;
+                               goto fail;
+                       }
+
+                       lnk->unparsed_path_length = unparsed;
                        *_symlink_err = symlink_err;
 
                        goto fail;
@@ -1177,7 +1187,7 @@ next:
        }
 
        if (!lp_follow_symlinks(SNUM(conn))) {
-               status = (symlink_err->unparsed == 0)
+               status = (lnk->unparsed_path_length == 0)
                                 ? NT_STATUS_OBJECT_NAME_NOT_FOUND
                                 : NT_STATUS_OBJECT_PATH_NOT_FOUND;
                TALLOC_FREE(symlink_err);
@@ -1199,7 +1209,7 @@ next:
        target = symlink_target_path(mem_ctx,
                                     name_in,
                                     lnk->substitute_name,
-                                    symlink_err->unparsed);
+                                    lnk->unparsed_path_length);
        if (target == NULL) {
                return NT_STATUS_NO_MEMORY;
        }
@@ -1208,7 +1218,7 @@ next:
                                          conn->connectpath,
                                          NULL,
                                          target,
-                                         symlink_err->unparsed,
+                                         lnk->unparsed_path_length,
                                          &safe_target);
        TALLOC_FREE(symlink_err);
        if (!NT_STATUS_IS_OK(status)) {
index 6e7997340137fb42a34ce174a0e7b6554d59ac06..e223034acc06b9ce512043b1273f7e42563a9f52 100644 (file)
@@ -1247,7 +1247,14 @@ next:
                if (next != NULL) {
                        size_t parsed = next - path;
                        size_t len = talloc_get_size(path);
-                       symlink_err->unparsed = len - parsed;
+                       size_t unparsed = len - parsed;
+
+                       if (unparsed > UINT16_MAX) {
+                               status = NT_STATUS_BUFFER_OVERFLOW;
+                               goto fail;
+                       }
+                       symlink_err->parsed.lnk
+                               .unparsed_path_length = unparsed;
                }
 
                /*
@@ -1287,7 +1294,7 @@ next:
 #endif
 
        if ((fd == -1) && (errno == ENOTDIR)) {
-               size_t parsed, len;
+               size_t parsed, len, unparsed;
 
                /*
                 * dirfsp does not point at a directory, try a
@@ -1308,7 +1315,15 @@ next:
 
                parsed = rel_fname.base_name - path;
                len = talloc_get_size(path);
-               symlink_err->unparsed = len - parsed;
+               unparsed = len - parsed;
+
+               if (unparsed > UINT16_MAX) {
+                       status = NT_STATUS_BUFFER_OVERFLOW;
+                       goto fail;
+               }
+
+               symlink_err->reparse->parsed.lnk
+                       .unparsed_path_length = unparsed;
 
                status = NT_STATUS_STOPPED_ON_SYMLINK;
                goto fail;
index fcc7c0dc3266733d9186ca8f8bb4a7080b7eafdb..c668a62b6e63590a9cc0bf4156538513c048bce3 100644 (file)
@@ -378,7 +378,6 @@ NTSTATUS open_stream_pathref_fsp(
        struct smb_filename *smb_fname);
 
 struct open_symlink_err {
-       size_t unparsed;
        struct reparse_data_buffer *reparse;
 };