FelipeMdeO commented on code in PR #3532:
URL: https://github.com/apache/nuttx-apps/pull/3532#discussion_r3459784604
##########
netutils/dropbear/port/nuttx_compat.c:
##########
@@ -0,0 +1,78 @@
+/****************************************************************************
+ * apps/netutils/dropbear/port/nuttx_compat.c
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include "config.h"
+
+#include <sys/types.h>
+#include <errno.h>
+#include <grp.h>
+#include <unistd.h>
+
+/****************************************************************************
+ * Private Data
+ ****************************************************************************/
+
+static char g_dropbear_shell[] = "/bin/sh";
+static int g_shell_returned;
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+void dropbear_setusershell(void)
+{
+ g_shell_returned = 0;
+}
+
+FAR char *dropbear_getusershell(void)
+{
+ if (g_shell_returned == 0)
+ {
+ g_shell_returned = 1;
+ return g_dropbear_shell;
+ }
+
+ return NULL;
+}
+
+void dropbear_endusershell(void)
+{
+ g_shell_returned = 0;
+}
+
+int dropbear_getgroups(int size, gid_t list[])
+{
+ (void)size;
+ (void)list;
+
+ errno = ENOSYS;
+ return -1;
+}
+
+int link(FAR const char *path1, FAR const char *path2)
Review Comment:
Dropbear uses link() in gensignkey.c:160 to atomically write the host key:
it writes to a temp file, then calls link(tmp, final) expecting a hard link so
both names reference the same inode. When tmp is later removed, the data
survives through final. With a symlink instead, final would become a dangling
pointer after tmp is deleted — silently losing the host key.
Therefore, the safe fallback (non-atomic write via buf_writefile) is only
triggered when link() returns an error such as ENOSYS. If the symlink-based
link() returns success, Dropbear proceeds assuming hard link semantics and the
key gets lost.
For more details, please look for the code below
netutils/dropbear/dropbear/src/gensignkey.c:154
(1) Key content is written to a temporary file only
`ret = buf_writefile(buf, fn_temp, 0);
`
(2) link() is expected to create a hard link:
both fn_temp and filename reference the same inode.
If link() fails with ENOSYS/EPERM/EACCES, Dropbear falls back
to writing filename directly (buf_writefile).
If link() succeeds, Dropbear assumes filename already holds the
key via the shared inode — no additional write is done.
```
if (link(fn_temp, filename) < 0) {
if (errno == EPERM || errno == EACCES || errno == ENOSYS) {
/* safe fallback: write content directly to filename */
ret = buf_writefile(buf, filename, skip_exist);
}
goto out;
}
```
success path: key is accessible via filename through the hard link
`fsync_parent_dir(filename);`
out:
(3) fn_temp is always deleted here.
With a hard link: filename still holds the inode — key survives.
With a symlink: filename points to fn_temp, which is now
deleted — dangling symlink, key is lost.
` unlink(fn_temp);`
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: [email protected]
For queries about this service, please contact Infrastructure at:
[email protected]