mirror of
https://github.com/apache/nuttx.git
synced 2026-10-07 22:35:22 +00:00
libc/termios: Fix the ttyname_r buffer overflow with long tty paths.
ttyname_r() passed the caller buffer straight to fcntl(F_GETPATH) whenever buflen >= TTY_NAME_MAX, but every FIOC_FILEPATH handler writes the path bounded by PATH_MAX and ignores the caller buffer size. A tty registered under a nested /dev path, or reached through rpmsgfs, has a path longer than TTY_NAME_MAX and overwrote the caller buffer, silently corrupting memory behind a zero return code. The small-buffer branch had the same defect against its own stack local char name[TTY_NAME_MAX]. Gate the direct write on PATH_MAX instead and stage the path through a PATH_MAX path buffer obtained via lib_get_tempbuffer(), returning ERANGE when it does not fit. Verified on sim:nsh with a test driver registered at an 85-character tty path: pre-fix, ttyname_r(buf, TTY_NAME_MAX) returned 0 and smashed the canaries behind the buffer, and the small-buffer branch panicked; post-fix both cases return ERANGE with the canaries intact. Assisted-by: Claude Code (glm-5.3) <claude@anthropic.com> Signed-off-by: Junbo Zheng <zhengjunbo1@xiaomi.com>
This commit is contained in:
parent
acc7d9bd3c
commit
82b2f1993b
1 changed files with 24 additions and 11 deletions
|
|
@ -29,6 +29,8 @@
|
|||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include <nuttx/lib/lib.h>
|
||||
|
||||
/****************************************************************************
|
||||
* Public Functions
|
||||
****************************************************************************/
|
||||
|
|
@ -63,25 +65,36 @@ int ttyname_r(int fd, FAR char *buf, size_t buflen)
|
|||
return ENOTTY;
|
||||
}
|
||||
|
||||
if (buflen >= TTY_NAME_MAX)
|
||||
/* The F_GETPATH handler copies the file path into the caller buffer
|
||||
* bounded by PATH_MAX, not by any tty-specific limit, so the path must
|
||||
* always land in a PATH_MAX-sized buffer first. Only a caller buffer
|
||||
* of that size can receive it directly.
|
||||
*/
|
||||
|
||||
if (buflen >= PATH_MAX)
|
||||
{
|
||||
return fcntl(fd, F_GETPATH, buf) < 0 ? get_errno() : 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
char name[TTY_NAME_MAX];
|
||||
FAR char *path = lib_get_tempbuffer(PATH_MAX);
|
||||
int ret;
|
||||
|
||||
if (fcntl(fd, F_GETPATH, name) < 0)
|
||||
if (fcntl(fd, F_GETPATH, path) < 0)
|
||||
{
|
||||
return get_errno();
|
||||
ret = get_errno();
|
||||
}
|
||||
else if (strlen(path) >= buflen)
|
||||
{
|
||||
ret = ERANGE;
|
||||
}
|
||||
else
|
||||
{
|
||||
strlcpy(buf, path, buflen);
|
||||
ret = OK;
|
||||
}
|
||||
|
||||
if (strlen(name) >= buflen)
|
||||
{
|
||||
return ERANGE;
|
||||
}
|
||||
|
||||
strlcpy(buf, name, buflen);
|
||||
return OK;
|
||||
lib_put_tempbuffer(path);
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue