This is an automated email from the ASF dual-hosted git repository. GUIDINGLI pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/nuttx.git
commit 24d371c0fe89e6f8f9628662c9427b1ef5112c1a Author: guohao15 <[email protected]> AuthorDate: Mon Sep 15 16:28:51 2025 +0800 fs/inode: return ENAMETOOLONG for path/filename longer than NAME_MAX Add a helper _inode_checkpath() that validates the path before the search: it returns -ENOENT for an empty path and -ENAMETOOLONG when any single path component exceeds NAME_MAX or the whole path exceeds PATH_MAX. inode_search() now runs this check first so that oversized paths and file names are rejected with the correct POSIX error code. Signed-off-by: guohao15 <[email protected]> --- fs/inode/fs_inodesearch.c | 80 +++++++++++++++++++++++++++++++---------------- 1 file changed, 53 insertions(+), 27 deletions(-) diff --git a/fs/inode/fs_inodesearch.c b/fs/inode/fs_inodesearch.c index ce7ae41f517..2f01a63c485 100644 --- a/fs/inode/fs_inodesearch.c +++ b/fs/inode/fs_inodesearch.c @@ -240,6 +240,40 @@ static int _compute_path_depth(FAR const char *path) return depth; } +/**************************************************************************** + * Name: _inode_checkpath + ****************************************************************************/ + +static int _inode_checkpath(const char *path) +{ + int namelen = 0; + int pathlen = 0; + + if (*path == '\0') + { + return -ENOENT; + } + + /* Check each segment of the path */ + + while (*path != '\0' && namelen < NAME_MAX && pathlen < PATH_MAX) + { + if (*path == '/') + { + namelen = 0; + } + else + { + namelen++; + } + + path++; + pathlen++; + } + + return *path != '\0' ? -ENAMETOOLONG : OK; +} + /**************************************************************************** * Name: _inode_search * @@ -268,20 +302,31 @@ static int _inode_search(FAR struct inode_search_s *desc) FAR struct inode *left = NULL; FAR struct inode *above = NULL; FAR const char *relpath = NULL; - int ret = -ENOENT; + int ret; - /* Get the search path, skipping over the leading '/'. The leading '/' is - * mandatory because only absolute paths are expected in this context. - */ + ret = _inode_checkpath(desc->path); + if (ret < 0) + { + return ret; + } - DEBUGASSERT(desc != NULL && desc->path != NULL); - name = desc->path; + /* Convert the relative path to the absolute path */ - if (*name != '/') + if (*desc->path != '/') { - return -EINVAL; + desc->buffer = lib_get_tempbuffer(PATH_MAX); + if (desc->buffer == NULL) + { + return -ENOMEM; + } + + snprintf(desc->buffer, PATH_MAX, "%s/%s", _inode_getcwd(), desc->path); + desc->path = desc->buffer; } + name = desc->path; + ret = -ENOENT; + /* Traverse the pseudo file system node tree until either (1) all nodes * have been examined without finding the matching node, or (2) the * matching node is found. @@ -557,25 +602,6 @@ int inode_search(FAR struct inode_search_s *desc) DEBUGASSERT(desc != NULL && desc->path != NULL); - if (*desc->path == '\0') - { - return -ENOENT; - } - - /* Convert the relative path to the absolute path */ - - if (*desc->path != '/') - { - desc->buffer = lib_get_tempbuffer(PATH_MAX); - if (desc->buffer == NULL) - { - return -ENOMEM; - } - - snprintf(desc->buffer, PATH_MAX, "%s/%s", _inode_getcwd(), desc->path); - desc->path = desc->buffer; - } - ret = _inode_search(desc); #ifdef CONFIG_FS_LINKS
