From: Namjae Jeon <linkinjeon@kernel.org>
To: linux-cifs@vger.kernel.org
Cc: senozhatsky@chromium.org, tom@talpey.com,
atteh.mailbox@gmail.com, chenxiaosong@chenxiaosong.com,
chenxiaosong@kylinos.cn, Namjae Jeon <linkinjeon@kernel.org>
Subject: [PATCH 14/22] ksmbd: enforce POSIX append-only writes
Date: Sat, 17 Oct 2026 10:03:36 +0900 [thread overview]
Message-ID: <20261017010344.11478-14-linkinjeon@kernel.org> (raw)
In-Reply-To: <20261017010344.11478-1-linkinjeon@kernel.org>
POSIX append-only opens do not set O_APPEND, and the SMB append sentinel
is rejected as a negative write offset.
Track append-only POSIX opens, set O_APPEND and require the U64_MAX
offset sentinel for their writes. Accept FILE_WRITE_DATA or
FILE_APPEND_DATA for WRITE requests, preserving ordinary SMB write
permissions. Use the POSIX append flag and offset check to prevent
POSIX append-only opens from overwriting existing data.
For synchronous writes, derive the fsync range from the completed write
position so append writes flush the range actually written.
Signed-off-by: Namjae Jeon <linkinjeon@kernel.org>
---
fs/smb/server/smb2pdu.c | 14 ++++++++++++--
fs/smb/server/vfs.c | 3 +--
fs/smb/server/vfs_cache.h | 1 +
3 files changed, 14 insertions(+), 4 deletions(-)
diff --git a/fs/smb/server/smb2pdu.c b/fs/smb/server/smb2pdu.c
index a1e553ddde46..396f10fb2a91 100644
--- a/fs/smb/server/smb2pdu.c
+++ b/fs/smb/server/smb2pdu.c
@@ -4736,6 +4736,9 @@ int smb2_open(struct ksmbd_work *work)
&may_flags,
req->CreateOptions,
file_present ? d_inode(path.dentry)->i_mode : 0);
+ if (posix_ctxt && (req->DesiredAccess & FILE_APPEND_DATA_LE) &&
+ !(req->DesiredAccess & FILE_WRITE_DATA_LE))
+ open_flags |= O_APPEND;
if (!test_tree_conn_flag(tcon, KSMBD_TREE_CONN_FLAG_WRITABLE)) {
if (open_flags & (O_CREAT | O_TRUNC)) {
@@ -4975,6 +4978,7 @@ int smb2_open(struct ksmbd_work *work)
FILE_WRITE_ATTRIBUTES_LE | FILE_SYNCHRONIZE_LE));
fp->is_posix_ctxt = posix_ctxt;
+ fp->posix_append = posix_ctxt && !!(open_flags & O_APPEND);
/* fp should be searchable through ksmbd_inode.m_fp_list
* after daccess, saccess, attrib_only, and stream are
@@ -10223,6 +10227,7 @@ int smb2_write(struct ksmbd_work *work)
ssize_t nbytes;
char *data_buf;
bool writethrough = false, is_rdma_channel = false;
+ bool append_write;
bool async_interim = false;
bool chseq_err = false;
int err = 0;
@@ -10254,7 +10259,8 @@ int smb2_write(struct ksmbd_work *work)
return smb2_write_pipe(work);
}
- offset = le64_to_cpu(req->Offset);
+ append_write = le64_to_cpu(req->Offset) == U64_MAX;
+ offset = append_write ? 0 : le64_to_cpu(req->Offset);
if (offset < 0) {
err = -EINVAL;
goto out;
@@ -10357,11 +10363,15 @@ int smb2_write(struct ksmbd_work *work)
goto out;
}
- if (!(fp->daccess & (FILE_WRITE_DATA_LE | FILE_READ_ATTRIBUTES_LE))) {
+ if (!(fp->daccess & (FILE_WRITE_DATA_LE | FILE_APPEND_DATA_LE))) {
pr_err("Not permitted to write : 0x%x\n", fp->daccess);
err = -EACCES;
goto out;
}
+ if (append_write != fp->posix_append) {
+ err = -EINVAL;
+ goto out;
+ }
if (work->next_smb2_rcv_hdr_off && !req->hdr.NextCommand) {
err = setup_async_work(work, NULL, NULL);
diff --git a/fs/smb/server/vfs.c b/fs/smb/server/vfs.c
index 181d27f43f31..f917f6aeb84d 100644
--- a/fs/smb/server/vfs.c
+++ b/fs/smb/server/vfs.c
@@ -526,7 +526,6 @@ int ksmbd_vfs_write(struct ksmbd_work *work, struct ksmbd_file *fp,
ssize_t *written)
{
struct file *filp;
- loff_t offset = *pos;
int err = 0;
if (work->conn->connection_type) {
@@ -573,7 +572,7 @@ int ksmbd_vfs_write(struct ksmbd_work *work, struct ksmbd_file *fp,
*written = err;
err = 0;
if (sync) {
- err = vfs_fsync_range(filp, offset, offset + *written, 0);
+ err = vfs_fsync_range(filp, *pos - *written, *pos, 0);
if (err < 0)
pr_err("fsync failed for filename = %pD, err = %d\n",
fp->filp, err);
diff --git a/fs/smb/server/vfs_cache.h b/fs/smb/server/vfs_cache.h
index 1054002ec4c5..064a053b92b1 100644
--- a/fs/smb/server/vfs_cache.h
+++ b/fs/smb/server/vfs_cache.h
@@ -173,6 +173,7 @@ struct ksmbd_file {
bool durable_replay_consumed;
bool is_posix_ctxt;
+ bool posix_append;
struct durable_owner owner;
__le16 channel_sequence;
unsigned int outstanding_requests;
--
2.25.1
next prev parent reply other threads:[~2026-10-17 1:04 UTC|newest]
Thread overview: 22+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-10-17 1:03 [PATCH 01/22] ksmbd: release connection lock while draining old session Namjae Jeon
2026-10-17 1:03 ` [PATCH 02/22] ksmbd: serialize oplock break ACK state updates Namjae Jeon
2026-10-17 1:03 ` [PATCH 03/22] ksmbd: track delivery of queued TCP writes Namjae Jeon
2026-10-17 1:03 ` [PATCH 04/22] ksmbd: retry break notifications on another connection Namjae Jeon
2026-10-17 1:03 ` [PATCH 05/22] ksmbd: keep lease tables until their last lease is closed Namjae Jeon
2026-10-17 1:03 ` [PATCH 06/22] ksmbd: index byte-range locks independently of their connection Namjae Jeon
2026-10-17 1:03 ` [PATCH 07/22] ksmbd: rebind completed CREATE replays without draining the old channel Namjae Jeon
2026-10-17 1:03 ` [PATCH 08/22] ksmbd: track SMB2 locks above OFFSET_MAX in server lock table Namjae Jeon
2026-10-17 1:03 ` [PATCH 09/22] ksmbd: expire unacknowledged oplock breaks Namjae Jeon
2026-10-17 1:03 ` [PATCH 10/22] ksmbd: expire unacknowledged lease breaks Namjae Jeon
2026-10-17 1:03 ` [PATCH 11/22] ksmbd: support SMB2 quota query and set information Namjae Jeon
2026-10-17 1:03 ` [PATCH 12/22] ksmbd: validate POSIX negotiate contexts Namjae Jeon
2026-10-17 1:03 ` [PATCH 13/22] ksmbd: validate POSIX create contexts Namjae Jeon
2026-10-17 1:03 ` Namjae Jeon [this message]
2026-10-17 1:03 ` [PATCH 15/22] ksmbd: apply byte-range lock checks per open Namjae Jeon
2026-10-17 1:03 ` [PATCH 16/22] ksmbd: use requested mode in POSIX creates Namjae Jeon
2026-10-17 1:03 ` [PATCH 17/22] ksmbd: apply POSIX mode ACEs in security updates Namjae Jeon
2026-10-17 1:03 ` [PATCH 18/22] ksmbd: correct POSIX file metadata in responses Namjae Jeon
2026-10-17 1:03 ` [PATCH 19/22] ksmbd: include filenames in POSIX query info Namjae Jeon
2026-10-17 1:03 ` [PATCH 20/22] ksmbd: require POSIX opens for file and directory queries Namjae Jeon
2026-10-17 1:03 ` [PATCH 21/22] ksmbd: query POSIX filesystem info through the open file Namjae Jeon
2026-10-17 1:03 ` [PATCH 22/22] ksmbd: correct POSIX filesystem block size and response length Namjae Jeon
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20261017010344.11478-14-linkinjeon@kernel.org \
--to=linkinjeon@kernel.org \
--cc=atteh.mailbox@gmail.com \
--cc=chenxiaosong@chenxiaosong.com \
--cc=chenxiaosong@kylinos.cn \
--cc=linux-cifs@vger.kernel.org \
--cc=senozhatsky@chromium.org \
--cc=tom@talpey.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox