Skip to content

sched/nsh: Remove Hard-coded Default Password#18396

Open
Abhishekmishra2808 wants to merge 3 commits intoapache:masterfrom
Abhishekmishra2808:Issue-16822
Open

sched/nsh: Remove Hard-coded Default Password#18396
Abhishekmishra2808 wants to merge 3 commits intoapache:masterfrom
Abhishekmishra2808:Issue-16822

Conversation

@Abhishekmishra2808
Copy link

@Abhishekmishra2808 Abhishekmishra2808 commented Feb 15, 2026

Summary

This PR introduces build-time generation of the /etc/passwd file for the ROMFS image when authentication is enabled.

Instead of relying on a static etc/passwd file embedded in the source tree, the passwd entry is now generated during the build using the configuration values:

  • CONFIG_ETC_ROMFS_PASSWD_USER
  • CONFIG_ETC_ROMFS_PASSWD_PASSWORD
  • CONFIG_ETC_ROMFS_PASSWD_UID
  • CONFIG_ETC_ROMFS_PASSWD_GID
  • CONFIG_ETC_ROMFS_PASSWD_HOME

The generated passwd entry is written into the ROMFS staging directory and included in the firmware image.

Behavior

Authentication disabled

  • No passwd generation occurs.
  • System behavior remains unchanged.

Authentication enabled

  • The build generates /etc/passwd automatically.
  • The password is hashed before being stored in the ROMFS image.
  • The plaintext password is never embedded in the firmware.

Password missing

  • If CONFIG_ETC_ROMFS_GENPASSWD=y but the password is empty, the build fails with an explicit error.

This ensures that credentials are always explicitly configured when authentication is enabled and prevents firmware images from being built with empty passwords.

Security Improvement

Previously /etc/passwd could be included as a static file in the ROMFS source tree.
With this change, the credentials are generated at build time and must be explicitly configured, avoiding implicit or default credentials in firmware images.

Testing

Generated passwd entry

image

Plaintext password check
image

(no output)

Build failure when password is empty

image

@github-actions github-actions bot added Area: Documentation Improvements or additions to documentation Area: Tooling Area: Build system Area: OS Components OS Components issues Board: risc-v Board: simulator Size: M The size of the change in this PR is medium labels Feb 15, 2026
@Abhishekmishra2808 Abhishekmishra2808 changed the title sched/nsh: Remove hard-coded default password and implement build-tim… sched/nsh: Remove Hard-coded Default Password (Security Fix for Issue #16822) Feb 15, 2026
@acassis
Copy link
Contributor

acassis commented Feb 15, 2026

@Abhishekmishra2808 the Documentation and the boardshould be (each one) in a separated. Normally we separate the logic implementation from the board support and Documentation.

@cederom
Copy link
Contributor

cederom commented Feb 15, 2026

Thank you @Abhishekmishra2808 :-)

  • I have updated description from "critical security vulnerability" to "improve security", as setting password is optional and user controllable, so it was always matter or user choice and decision what the password would be.. here we want to remove the default, correct?
  • Do you use AI for code and description generation?

@Abhishekmishra2808
Copy link
Author

Hi @cederom ,
Yes, the goal is to remove the default password from the defconfigs and avoid having any hardcoded credentials. Password generation should be explicitly enabled and configured by the user when needed.

I used AI tools only to help refine wording and improve clarity in the description, but the implementation, debugging, and testing were done by me.

@Abhishekmishra2808
Copy link
Author

@acassis I have fixed the changes suggested by you, and CI was failing because password generation was enabled in the defconfig files without setting a password. I have now removed CONFIG_ETC_ROMFS_GENPASSWD from the affected defconfigs so that password generation is not enabled by default. This ensures there is no default password while allowing users to explicitly enable and configure it if needed.

@Abhishekmishra2808 Abhishekmishra2808 changed the title sched/nsh: Remove Hard-coded Default Password (Security Fix for Issue #16822) sched/nsh: Remove Hard-coded Default Password Feb 15, 2026
@acassis
Copy link
Contributor

acassis commented Mar 17, 2026

@Abhishekmishra2808 please normalize the boards/sim/sim/sim/configs/login/defconfig to this the CI error, run:

$ ./tools/refresh.sh --silent sim:login

And then squash the modification to your previous commit

@github-actions github-actions bot added Size: XL The size of the change in this PR is very large. Consider breaking down the PR into smaller pieces. and removed Size: L The size of the change in this PR is large labels Mar 17, 2026
.. code:: console

$ grep <your-password> boards/<arch>/<chip>/<board>/src/etctmp.c
# must print nothing
Copy link
Contributor

@acassis acassis Mar 17, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@Abhishekmishra2808 could you please add at the end of this Documentation explaining that to avoid leaking user password (CONFIG_BOARD_ETC_ROMFS_PASSWD_PASSWORD) and keys (CONFIG_FSUTILS_PASSWD_KEY1-4) when user run "make savedefconfig" it will not be saved in the defconfig. And if the user needs it in their local defconfig they need to add it manually in their defconfig.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks- addressed this in the latest commit.

@acassis
Copy link
Contributor

acassis commented Mar 17, 2026

@Abhishekmishra2808 you need to analyze the errors (just click in the task that failed) and scroll the errors

Seem like many boards need to be normalized after that, just an example:

NOTE: CONFIG_FSUTILS_PASSWD_KEY1-4 are intentionally excluded by

"make savedefconfig" to avoid leaking credentials into mainline.

CONFIG_BOARD_ETC_ROMFS_PASSWD_PASSWORD is excluded by default,

except for the sim:login example configuration.

credentials into mainline. Add them manually in local defconfig if needed.

Saving the new configuration file
HEAD detached at pull/18396/merge
Changes not staged for commit:
(use "git add ..." to update what will be committed)
(use "git restore ..." to discard changes in working directory)
modified: boards/x86_64/qemu/qemu-intel64/configs/earlyfb/defconfig
modified: boards/x86_64/qemu/qemu-intel64/configs/fb/defconfig
modified: boards/x86_64/qemu/qemu-intel64/configs/knsh_romfs/defconfig
modified: boards/x86_64/qemu/qemu-intel64/configs/lvgl/defconfig
modified: boards/x86_64/qemu/qemu-intel64/configs/nsh/defconfig
modified: boards/x86_64/qemu/qemu-intel64/configs/nsh_pci/defconfig
modified: boards/x86_64/qemu/qemu-intel64/configs/nsh_pci_smp/defconfig
modified: boards/x86_64/qemu/qemu-intel64/configs/ostest/defconfig

See here how to normalize many profiles are same time (for a board, or a chip family, etc)

https://nuttx.apache.org/docs/latest/components/tools/refresh.html

@Abhishekmishra2808
Copy link
Author

Finally, CI turned green, ready to get final approvals :)

acassis
acassis previously approved these changes Mar 19, 2026
@acassis
Copy link
Contributor

acassis commented Mar 19, 2026

@raiden00pl please review again!

endforeach()

message(
WARNING "CONFIG_BOARD_ETC_ROMFS_PASSWD_PASSWORD and"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why not move to the first patch? the change should be completed in one patch

@xiaoxiang781216
Copy link
Contributor

@Abhishekmishra2808 could you refine your patchset?

  1. The general change for Makefile/Cmake/Kconfig/source in first patch
  2. Migrate the old method in each board to new method in second patch
  3. Documentation in the last patch

@Abhishekmishra2808
Copy link
Author

@xiaoxiang781216 Thanks for the review feedback. I've refined the patchset as requested and addressed all the comments you made, please check.

@github-actions github-actions bot added Size: L The size of the change in this PR is large and removed Size: XL The size of the change in this PR is very large. Consider breaking down the PR into smaller pieces. labels Mar 21, 2026
@raiden00pl raiden00pl dismissed their stale review March 22, 2026 10:31

Dismiss

tools/Unix.mk Outdated
$(Q) rm -f warning.tmp
$(Q) rm -f defconfig.tmp
$(Q) rm -f sortedconfig.tmp
$(Q) echo "WARNING: CONFIG_BOARD_ETC_ROMFS_PASSWD_PASSWORD was not saved in defconfig."
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

could you remove the warning

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agree, I will remove unconditional warning prints. I will only print this warning when ETC passwd autogen is enabled during savedefconfig, so users are informed only when it is relevant.

WARNING "CONFIG_BOARD_ETC_ROMFS_PASSWD_PASSWORD and"
" CONFIG_FSUTILS_PASSWD_KEY1-4 were intentionally excluded from"
" defconfig by savedefconfig to avoid leaking credentials."
" Add them manually in local defconfig if needed.")
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why always output warning

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@Abhishekmishra2808 @xiaoxiang781216 this warning should be printed when to user enabled the ETC PASSWD and run "make savedefconfig", it is printed to warn the user that the password and keys cannot be stored automatically in the generated defconfig

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good point. I will make the warning conditional in CMake as well, same behavior as Make path, so it is not always noisy but still warns users when password/key values are intentionally excluded.

boards/Board.mk Outdated
$(call PREPROCESS, $<, $@)

$(ETCSRC): $(foreach raw,$(RCRAWS), $(if $(wildcard $(BOARD_DIR)$(DELIM)src$(DELIM)$(raw)), $(BOARD_DIR)$(DELIM)src$(DELIM)$(raw), $(if $(wildcard $(BOARD_COMMON_DIR)$(DELIM)$(raw)), $(BOARD_COMMON_DIR)$(DELIM)$(raw), $(BOARD_DIR)$(DELIM)src$(DELIM)$(raw)))) $(RCOBJS)
$(ETCSRC): $(foreach raw,$(RCRAWS), $(if $(wildcard $(BOARD_DIR)$(DELIM)src$(DELIM)$(raw)), $(BOARD_DIR)$(DELIM)src$(DELIM)$(raw), $(if $(wildcard $(BOARD_COMMON_DIR)$(DELIM)$(raw)), $(BOARD_COMMON_DIR)$(DELIM)$(raw), $(BOARD_DIR)$(DELIM)src$(DELIM)$(raw)))) $(RCOBJS) $(TOPDIR)$(DELIM).config $(TOPDIR)$(DELIM)tools$(DELIM)mkpasswd.c
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

don't need add the dependence, since you build mkpasswd in action manually

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

accepted

boards/Board.mk Outdated
ifeq ($(CONFIG_BOARD_ETC_ROMFS_PASSWD_PASSWORD),"")
$(error CONFIG_BOARD_ETC_ROMFS_PASSWD_PASSWORD must be set when BOARD_ETC_ROMFS_PASSWD_ENABLE is enabled. Run 'make menuconfig' to set a password.)
endif
$(Q) if [ ! -f $(TOPDIR)$(DELIM)tools$(DELIM)mkpasswd$(HOSTEXEEXT) ] || \
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why need change the existence of mkpasswd? make will do it automatically

boards/Board.mk Outdated
ifeq ($(CONFIG_BOARD_ETC_ROMFS_PASSWD_PASSWORD),)
$(error CONFIG_BOARD_ETC_ROMFS_PASSWD_PASSWORD must be set when BOARD_ETC_ROMFS_PASSWD_ENABLE is enabled. Run 'make menuconfig' to set a password.)
endif
ifeq ($(CONFIG_BOARD_ETC_ROMFS_PASSWD_PASSWORD),"")
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

remove the check since mkpasswd already do the check

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think the idea here is to verify if the user defined the password in the "menuconfig"

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

mkpasswd already check it, why dup the check in many places

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Right, maybe keeping the testing only is mkpasswd is enough, but we need to understand where is better to report the error. I think failing early is better to let user to fix the issue. @Abhishekmishra2808 please comment your idea here

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

for me I think we should keep mkpasswd as the source of truth for validation and keep only one early empty password check for better user feedback when the feature is enabled. this avoids duplicated checks while still failing early with a clear message. For savedefconfig, we can print the warning conditionally only when this feature is enabled, so users are informed without adding noise.

boards/Kconfig Outdated

config BOARD_ETC_ROMFS_PASSWD_PASSWORD
string "Admin password (required)"
default ""
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

remove the default value

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If the test to verify if the user defined a password is used, I think the default password needs to be defined here as empty, so seems correct, isn't it?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we can satisfy both points by keeping the behavior but removing redundancy: I’ll remove the explicit default "" line (since empty is already implicit for string Kconfig symbols), and I’ll keep the fail-fast check when passwd autogen is enabled so we still enforce that the user sets a password in menuconfig. So we keep the same user-facing behavior, but with cleaner Kconfig and less duplicated logic.


# Auto-generate /etc/passwd at build time if configured
if(CONFIG_BOARD_ETC_ROMFS_PASSWD_ENABLE)
if("${CONFIG_BOARD_ETC_ROMFS_PASSWD_PASSWORD}" STREQUAL "")
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

dditto

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same approach here as Make path: no duplicated detailed checks, only one early empty-password check for fail-fast feedback and leave full validation to mkpasswd.

@Abhishekmishra2808
Copy link
Author

I have shared my view in the thread above. If this aligns with everyone, I will implement the following in the next commit: keep mkpasswd as source of truth for detailed validation, keep one fail-fast empty-password check when passwd autogen is enabled, remove duplicated checks, make savedefconfig warning conditional, keep credentials excluded from generated defconfig, remove redundant explicit empty default in Kconfig, and ensure Make/CMake behavior stays consistent.
If you give the heads up, I will proceed.

Introduce mkpasswd, a host tool for generating encrypted password files
at build time using TEA encryption. This enables secure, credential-free
firmware images while allowing build-time password configuration.

Changes:
* Add mkpasswd.c host tool for TEA-based password hashing and encryption
* Integrate mkpasswd into Make build system (tools/Makefile.host)
* Add CMake support for mkpasswd compilation and ROMFS passwd generation
* Add CONFIG_BOARD_ETC_ROMFS_PASSWD_* configuration options to Kconfig
* Implement credential exclusion from defconfig to prevent password leaking
* Update savedefconfig.cmake to strip sensitive credentials
* Handle common build infrastructure for passwd file auto-generation
* Implement default-key warning detection in mkpasswd tool only

This provides generic framework before per-board migrations.

Signed-off-by: Abhishek Mishra <mishra.abhishek2808@gmail.com>
Migrate boards from static /etc/passwd files to build-time generation:

* Remove static etc/passwd files from SIM and ESP32-C3-legacy boards
* Update board configurations to enable BOARD_ETC_ROMFS_PASSWD_ENABLE
* Configure SIM board with login demo user (admin/Administrator)
* Update board build rules to use newly generated passwd files
* Remove CMakeLists.txt dependency on static passwd in SIM

This completes the infrastructure migration for boards supporting
login functionality.

Signed-off-by: Abhishek Mishra <mishra.abhishek2808@gmail.com>
Document the new mkpasswd-based password generation system and its
integration with the build process.

Changes:
* Add comprehensive mkpasswd tool documentation to components/tools
* Update SIM board docs to explain generated passwd workflow
* Update ESP32-C3-legacy board docs for passwd generation
* Update RX65N board docs with credential handling guidance
* Document how to configure and use BOARD_ETC_ROMFS_PASSWD_* options
* Explain security benefits of build-time generation vs static files

Helps users understand password configuration and security implications.

Signed-off-by: Abhishek Mishra <mishra.abhishek2808@gmail.com>
@github-actions github-actions bot added Size: XL The size of the change in this PR is very large. Consider breaking down the PR into smaller pieces. and removed Size: L The size of the change in this PR is large labels Mar 26, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Area: Build system Board: risc-v Board: simulator Size: XL The size of the change in this PR is very large. Consider breaking down the PR into smaller pieces.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[SECURITY] Avoid hard-coded default password

8 participants