From: Volker Lendecke Date: Tue, 24 Oct 2023 11:18:32 +0000 (+0200) Subject: smbd: Fix previous_slash() X-Git-Tag: talloc-2.4.2~946 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=ea1687054570d653b2f19197436ff00dc08089c2;p=thirdparty%2Fsamba.git smbd: Fix previous_slash() Untested code is broken code... previous_slash() did not return a pointer to the slash but after it. This went undetected because so far we never call symlink_target_path() with "unparsed==0". Once we started doing that, we would find that the "unparsed==0" case actually puts parent on the "previous slash", not the character behind it. Signed-off-by: Volker Lendecke Reviewed-by: Jeremy Allison --- diff --git a/source3/smbd/filename.c b/source3/smbd/filename.c index 3c54ab17762..29e3d9d19cf 100644 --- a/source3/smbd/filename.c +++ b/source3/smbd/filename.c @@ -879,26 +879,27 @@ lookup: static const char *previous_slash(const char *name_in, const char *slash) { - const char *prev = name_in; + const char *prev = NULL; - while (true) { - const char *next = strchr_m(prev, '/'); + SMB_ASSERT((name_in <= slash) && (slash[0] == '/')); - SMB_ASSERT(next != NULL); /* we have at least one slash */ + prev = strchr_m(name_in, '/'); - if (next == slash) { - break; - } + if (prev == slash) { + /* No previous slash */ + return NULL; + } - prev = next+1; - }; + while (true) { + const char *next = strchr_m(prev + 1, '/'); - if (prev == name_in) { - /* no previous slash */ - return NULL; + if (next == slash) { + return prev; + } + prev = next; } - return prev; + return NULL; /* unreachable */ } static char *symlink_target_path( @@ -928,17 +929,16 @@ static char *symlink_target_path( } if (parent == NULL) { - /* no previous slash */ - parent = name_in; + ret = talloc_asprintf(mem_ctx, "%s%s", substitute, p_unparsed); + } else { + ret = talloc_asprintf(mem_ctx, + "%.*s/%s%s", + (int)(parent - name_in), + name_in, + substitute, + p_unparsed); } - ret = talloc_asprintf( - mem_ctx, - "%.*s%s%s", - (int)(parent - name_in), - name_in, - substitute, - p_unparsed); return ret; }