Skip to content

wolfsftp: apply the attributes SETSTAT and FSETSTAT acknowledge - #1197

Open
yosuke-wolfssl wants to merge 1 commit into
wolfSSL:masterfrom
yosuke-wolfssl:fix/f_11658
Open

wolfsftp: apply the attributes SETSTAT and FSETSTAT acknowledge#1197
yosuke-wolfssl wants to merge 1 commit into
wolfSSL:masterfrom
yosuke-wolfssl:fix/f_11658

Conversation

@yosuke-wolfssl

@yosuke-wolfssl yosuke-wolfssl commented Aug 25, 2026

Copy link
Copy Markdown
Contributor

Problem

SFTP_SetFileAttributes() and SFTP_SetFileAttributesHandle() left the SIZE
and UIDGID operations as @TODO no-ops yet returned WS_SUCCESS, so
wolfSSH_SFTP_RecvSetSTAT() and wolfSSH_SFTP_RecvFSetSTAT() replied
SSH_FX_OK for truncate and chown requests that never happened. A client that
truncates a file and gets OK back reasonably believes the file is that length.

The same defect covered timestamps: WSETTIME/WFSETTIME existed only as (0)
stubs on every port, so TIME was silently discarded too.

Closes f-11658.

Fix (src/wolfsftp.c)

Every requested attribute is now applied or reported:

  • WTRUNCATE/WFTRUNCATE and WCHOWN/WFCHOWN carry out size and
    ownership changes; the 64-bit size is bounds-checked by the existing
    wResolveOffset() against WOLFSSH_MAX_FILE_OFFSET.
  • WSETTIME/WFSETTIME are real implementations built on the existing
    WUTIMES_NOFOLLOW/WFUTIMES helpers, inheriting their symlink hardening.
  • WS_UNIMPLEMENTED_E where a port defines no wrapper, which the handlers
    answer as SSH_FX_OP_UNSUPPORTED.
Flag POSIX Windows
SIZE truncate / ftruncate unsupported
UIDGID chown / fchown unsupported
PERM chmod / fchmod _wchmod via new WS_ChmodA()
TIME futimens / utimensat unsupported

Windows permissions needed more than the guard change. SFTP paths arrive as
/C:/..., which _chmod() rejects — every other Windows file routine in
port.c already strips that leading root via TrimFileName(). WS_ChmodA()
follows the same pattern, so WCHMOD works on Windows for the first time.

Client companion fix (required). wolfSSH_SFTP_CHMOD() STATs the target and
echoed the entire reply back, and the server's STAT sets every flag — so once the
server honours SIZE, a chmod asks it to truncate() the target, which fails on a
directory. It now sends only WOLFSSH_FILEATRB_PERM, matching OpenSSH's client.

Tests

  • TestSftpSetStatAttributes() drives both handlers for size, timestamp and
    ownership, asserting the on-disk result via WSTAT rather than the status
    alone, with separate root and non-root ownership paths.
  • tests/sftp.c adds an end-to-end chmod of a directory, guarding the client fix.

Verification

  • Negative controls fail first: pre-fix the status is OK while the file is
    unchanged; without the client fix the directory chmod fails; stubbing
    WFCHOWN fails the give-away-chown case.
  • regress.test passes as an ordinary user and under sudo, so both ownership
    branches execute. make check: 9 pass, 1 skip, 2 fail — both
    scripts/{sftp,scp}.test, which pass on serial re-run (known parallel flake).
  • GCC preflight clean across 6 configs; ASan + UBSan clean.
  • Windows MSVC: builds with SFTP enabled, api-test/unit-test pass, and an
    end-to-end chmod 400/chmod 600 over SFTP toggles the read-only attribute.
  • OpenSSH client interop: chmod on a directory and put -p both correct.

@yosuke-wolfssl yosuke-wolfssl self-assigned this Aug 25, 2026
Copilot AI lite review requested due to automatic review settings August 25, 2026 02:07

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

Fixes SFTP SETSTAT/FSETSTAT so the server only acknowledges attributes it actually applies (size/uid-gid/timestamps), returning SSH_FX_OP_UNSUPPORTED when a port lacks the needed wrappers. Also adjusts the built-in SFTP client’s chmod behavior to avoid unintentionally requesting unrelated attribute changes.

Changes:

  • Implement SIZE, UIDGID, and TIME application in SFTP_SetFileAttributes() / SFTP_SetFileAttributesHandle(), with WS_UNIMPLEMENTED_E mapped to SSH_FX_OP_UNSUPPORTED.
  • Add portable wrappers in port.h for truncate/chown and real WSETTIME/WFSETTIME implementations when supported.
  • Add regression and end-to-end tests covering SETSTAT/FSETSTAT attribute application and directory chmod behavior.

Reviewed changes

Copilot reviewed 4 out of 4 changed files in this pull request and generated 2 comments.

File Description
wolfssh/port.h Adds WTRUNCATE/WFTRUNCATE, WCHOWN/WFCHOWN, and functional WSETTIME/WFSETTIME wrappers where supported.
src/wolfsftp.c Applies SETSTAT/FSETSTAT attributes (or reports unsupported), and fixes client-side chmod to send only PERM.
tests/regress.c Adds a regression test ensuring SETSTAT/FSETSTAT really change size/time/ownership on disk.
tests/sftp.c Adds an end-to-end chmod-directory test to guard the client fix.

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment thread src/wolfsftp.c Outdated
Comment thread src/wolfsftp.c Outdated

@wolfSSL-Fenrir-bot wolfSSL-Fenrir-bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Fenrir Automated Review — PR #1197

Scan targets checked: wolfssh-bugs, wolfssh-src

Findings: 2
2 finding(s) posted as inline comments (see file-level comments below)

This review was generated automatically by Fenrir. Reported findings require changes before merge.

Comment thread src/wolfsftp.c Outdated
Comment thread tests/regress.c
Comment thread src/wolfsftp.c Outdated
Comment thread tests/regress.c

@wolfSSL-Fenrir-bot wolfSSL-Fenrir-bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Fenrir Automated Review — PR #1197

Scan targets checked: wolfssh-bugs, wolfssh-src

Findings: 1
1 finding(s) posted as inline comments (see file-level comments below)

This review was generated automatically by Fenrir. Reported findings require changes before merge.

Comment thread tests/regress.c
- SFTP_SetFileAttributes() and SFTP_SetFileAttributesHandle() carry
  out the size, ownership and timestamp requests, and set
  WS_UNIMPLEMENTED_E where the port defines no wrapper for one. Every
  branch runs only while ret is WS_SUCCESS, and the size is checked by
  wResolveOffset() against WOLFSSH_MAX_FILE_OFFSET.
- SFTP_SetMode() swaps its USE_WINDOWS_API guard for _WIN32_WCE, and
  the permission step of SFTP_SetFileAttributes() drops the matching
  guard, so permissions are applied on Windows.
- port.c adds WS_ChmodA(), which trims the SFTP leading root and calls
  _wchmod(); WCHMOD uses it on Windows SFTP and SCP builds.
- wolfSSH_SFTP_RecvSetSTAT() and wolfSSH_SFTP_RecvFSetSTAT() answer
  WOLFSSH_FTP_UNSUPPORTED for WS_UNIMPLEMENTED_E.
- wolfSSH_SFTP_CHMOD() sets the attribute flags to
  WOLFSSH_FILEATRB_PERM before sending.
- port.h adds WTRUNCATE, WFTRUNCATE, WCHOWN and WFCHOWN for the POSIX
  port, and defines WSETTIME and WFSETTIME over the existing WUTIMES
  and WFUTIMES helpers in place of their (0) definitions.
- tests/regress.c adds TestSftpSetStatAttributes(); tests/sftp.c adds
  a chmod of a directory.

Issue: F-11658
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants