Commit 6b4aa469 authored by Linus Torvalds's avatar Linus Torvalds

Merge tag '6.11-rc3-ksmbd-fixes' of git://git.samba.org/ksmbd

Pull smb server fixes from Steve French:
 "Two smb3 server fixes for access denied problem on share path checks"

* tag '6.11-rc3-ksmbd-fixes' of git://git.samba.org/ksmbd:
  ksmbd: override fsids for smb2_query_info()
  ksmbd: override fsids for share path check
parents d74da846 f6bd4128
...@@ -15,6 +15,7 @@ ...@@ -15,6 +15,7 @@
#include "share_config.h" #include "share_config.h"
#include "user_config.h" #include "user_config.h"
#include "user_session.h" #include "user_session.h"
#include "../connection.h"
#include "../transport_ipc.h" #include "../transport_ipc.h"
#include "../misc.h" #include "../misc.h"
...@@ -120,12 +121,13 @@ static int parse_veto_list(struct ksmbd_share_config *share, ...@@ -120,12 +121,13 @@ static int parse_veto_list(struct ksmbd_share_config *share,
return 0; return 0;
} }
static struct ksmbd_share_config *share_config_request(struct unicode_map *um, static struct ksmbd_share_config *share_config_request(struct ksmbd_work *work,
const char *name) const char *name)
{ {
struct ksmbd_share_config_response *resp; struct ksmbd_share_config_response *resp;
struct ksmbd_share_config *share = NULL; struct ksmbd_share_config *share = NULL;
struct ksmbd_share_config *lookup; struct ksmbd_share_config *lookup;
struct unicode_map *um = work->conn->um;
int ret; int ret;
resp = ksmbd_ipc_share_config_request(name); resp = ksmbd_ipc_share_config_request(name);
...@@ -181,7 +183,14 @@ static struct ksmbd_share_config *share_config_request(struct unicode_map *um, ...@@ -181,7 +183,14 @@ static struct ksmbd_share_config *share_config_request(struct unicode_map *um,
KSMBD_SHARE_CONFIG_VETO_LIST(resp), KSMBD_SHARE_CONFIG_VETO_LIST(resp),
resp->veto_list_sz); resp->veto_list_sz);
if (!ret && share->path) { if (!ret && share->path) {
if (__ksmbd_override_fsids(work, share)) {
kill_share(share);
share = NULL;
goto out;
}
ret = kern_path(share->path, 0, &share->vfs_path); ret = kern_path(share->path, 0, &share->vfs_path);
ksmbd_revert_fsids(work);
if (ret) { if (ret) {
ksmbd_debug(SMB, "failed to access '%s'\n", ksmbd_debug(SMB, "failed to access '%s'\n",
share->path); share->path);
...@@ -214,7 +223,7 @@ static struct ksmbd_share_config *share_config_request(struct unicode_map *um, ...@@ -214,7 +223,7 @@ static struct ksmbd_share_config *share_config_request(struct unicode_map *um,
return share; return share;
} }
struct ksmbd_share_config *ksmbd_share_config_get(struct unicode_map *um, struct ksmbd_share_config *ksmbd_share_config_get(struct ksmbd_work *work,
const char *name) const char *name)
{ {
struct ksmbd_share_config *share; struct ksmbd_share_config *share;
...@@ -227,7 +236,7 @@ struct ksmbd_share_config *ksmbd_share_config_get(struct unicode_map *um, ...@@ -227,7 +236,7 @@ struct ksmbd_share_config *ksmbd_share_config_get(struct unicode_map *um,
if (share) if (share)
return share; return share;
return share_config_request(um, name); return share_config_request(work, name);
} }
bool ksmbd_share_veto_filename(struct ksmbd_share_config *share, bool ksmbd_share_veto_filename(struct ksmbd_share_config *share,
......
...@@ -11,6 +11,8 @@ ...@@ -11,6 +11,8 @@
#include <linux/path.h> #include <linux/path.h>
#include <linux/unicode.h> #include <linux/unicode.h>
struct ksmbd_work;
struct ksmbd_share_config { struct ksmbd_share_config {
char *name; char *name;
char *path; char *path;
...@@ -68,7 +70,7 @@ static inline void ksmbd_share_config_put(struct ksmbd_share_config *share) ...@@ -68,7 +70,7 @@ static inline void ksmbd_share_config_put(struct ksmbd_share_config *share)
__ksmbd_share_config_put(share); __ksmbd_share_config_put(share);
} }
struct ksmbd_share_config *ksmbd_share_config_get(struct unicode_map *um, struct ksmbd_share_config *ksmbd_share_config_get(struct ksmbd_work *work,
const char *name); const char *name);
bool ksmbd_share_veto_filename(struct ksmbd_share_config *share, bool ksmbd_share_veto_filename(struct ksmbd_share_config *share,
const char *filename); const char *filename);
......
...@@ -16,17 +16,18 @@ ...@@ -16,17 +16,18 @@
#include "user_session.h" #include "user_session.h"
struct ksmbd_tree_conn_status struct ksmbd_tree_conn_status
ksmbd_tree_conn_connect(struct ksmbd_conn *conn, struct ksmbd_session *sess, ksmbd_tree_conn_connect(struct ksmbd_work *work, const char *share_name)
const char *share_name)
{ {
struct ksmbd_tree_conn_status status = {-ENOENT, NULL}; struct ksmbd_tree_conn_status status = {-ENOENT, NULL};
struct ksmbd_tree_connect_response *resp = NULL; struct ksmbd_tree_connect_response *resp = NULL;
struct ksmbd_share_config *sc; struct ksmbd_share_config *sc;
struct ksmbd_tree_connect *tree_conn = NULL; struct ksmbd_tree_connect *tree_conn = NULL;
struct sockaddr *peer_addr; struct sockaddr *peer_addr;
struct ksmbd_conn *conn = work->conn;
struct ksmbd_session *sess = work->sess;
int ret; int ret;
sc = ksmbd_share_config_get(conn->um, share_name); sc = ksmbd_share_config_get(work, share_name);
if (!sc) if (!sc)
return status; return status;
...@@ -61,7 +62,7 @@ ksmbd_tree_conn_connect(struct ksmbd_conn *conn, struct ksmbd_session *sess, ...@@ -61,7 +62,7 @@ ksmbd_tree_conn_connect(struct ksmbd_conn *conn, struct ksmbd_session *sess,
struct ksmbd_share_config *new_sc; struct ksmbd_share_config *new_sc;
ksmbd_share_config_del(sc); ksmbd_share_config_del(sc);
new_sc = ksmbd_share_config_get(conn->um, share_name); new_sc = ksmbd_share_config_get(work, share_name);
if (!new_sc) { if (!new_sc) {
pr_err("Failed to update stale share config\n"); pr_err("Failed to update stale share config\n");
status.ret = -ESTALE; status.ret = -ESTALE;
......
...@@ -13,6 +13,7 @@ ...@@ -13,6 +13,7 @@
struct ksmbd_share_config; struct ksmbd_share_config;
struct ksmbd_user; struct ksmbd_user;
struct ksmbd_conn; struct ksmbd_conn;
struct ksmbd_work;
enum { enum {
TREE_NEW = 0, TREE_NEW = 0,
...@@ -50,8 +51,7 @@ static inline int test_tree_conn_flag(struct ksmbd_tree_connect *tree_conn, ...@@ -50,8 +51,7 @@ static inline int test_tree_conn_flag(struct ksmbd_tree_connect *tree_conn,
struct ksmbd_session; struct ksmbd_session;
struct ksmbd_tree_conn_status struct ksmbd_tree_conn_status
ksmbd_tree_conn_connect(struct ksmbd_conn *conn, struct ksmbd_session *sess, ksmbd_tree_conn_connect(struct ksmbd_work *work, const char *share_name);
const char *share_name);
void ksmbd_tree_connect_put(struct ksmbd_tree_connect *tcon); void ksmbd_tree_connect_put(struct ksmbd_tree_connect *tcon);
int ksmbd_tree_conn_disconnect(struct ksmbd_session *sess, int ksmbd_tree_conn_disconnect(struct ksmbd_session *sess,
......
...@@ -1955,7 +1955,7 @@ int smb2_tree_connect(struct ksmbd_work *work) ...@@ -1955,7 +1955,7 @@ int smb2_tree_connect(struct ksmbd_work *work)
ksmbd_debug(SMB, "tree connect request for tree %s treename %s\n", ksmbd_debug(SMB, "tree connect request for tree %s treename %s\n",
name, treename); name, treename);
status = ksmbd_tree_conn_connect(conn, sess, name); status = ksmbd_tree_conn_connect(work, name);
if (status.ret == KSMBD_TREE_CONN_STATUS_OK) if (status.ret == KSMBD_TREE_CONN_STATUS_OK)
rsp->hdr.Id.SyncId.TreeId = cpu_to_le32(status.tree_conn->id); rsp->hdr.Id.SyncId.TreeId = cpu_to_le32(status.tree_conn->id);
else else
...@@ -5596,6 +5596,11 @@ int smb2_query_info(struct ksmbd_work *work) ...@@ -5596,6 +5596,11 @@ int smb2_query_info(struct ksmbd_work *work)
ksmbd_debug(SMB, "GOT query info request\n"); ksmbd_debug(SMB, "GOT query info request\n");
if (ksmbd_override_fsids(work)) {
rc = -ENOMEM;
goto err_out;
}
switch (req->InfoType) { switch (req->InfoType) {
case SMB2_O_INFO_FILE: case SMB2_O_INFO_FILE:
ksmbd_debug(SMB, "GOT SMB2_O_INFO_FILE\n"); ksmbd_debug(SMB, "GOT SMB2_O_INFO_FILE\n");
...@@ -5614,6 +5619,7 @@ int smb2_query_info(struct ksmbd_work *work) ...@@ -5614,6 +5619,7 @@ int smb2_query_info(struct ksmbd_work *work)
req->InfoType); req->InfoType);
rc = -EOPNOTSUPP; rc = -EOPNOTSUPP;
} }
ksmbd_revert_fsids(work);
if (!rc) { if (!rc) {
rsp->StructureSize = cpu_to_le16(9); rsp->StructureSize = cpu_to_le16(9);
...@@ -5623,6 +5629,7 @@ int smb2_query_info(struct ksmbd_work *work) ...@@ -5623,6 +5629,7 @@ int smb2_query_info(struct ksmbd_work *work)
le32_to_cpu(rsp->OutputBufferLength)); le32_to_cpu(rsp->OutputBufferLength));
} }
err_out:
if (rc < 0) { if (rc < 0) {
if (rc == -EACCES) if (rc == -EACCES)
rsp->hdr.Status = STATUS_ACCESS_DENIED; rsp->hdr.Status = STATUS_ACCESS_DENIED;
......
...@@ -732,10 +732,10 @@ bool is_asterisk(char *p) ...@@ -732,10 +732,10 @@ bool is_asterisk(char *p)
return p && p[0] == '*'; return p && p[0] == '*';
} }
int ksmbd_override_fsids(struct ksmbd_work *work) int __ksmbd_override_fsids(struct ksmbd_work *work,
struct ksmbd_share_config *share)
{ {
struct ksmbd_session *sess = work->sess; struct ksmbd_session *sess = work->sess;
struct ksmbd_share_config *share = work->tcon->share_conf;
struct cred *cred; struct cred *cred;
struct group_info *gi; struct group_info *gi;
unsigned int uid; unsigned int uid;
...@@ -775,6 +775,11 @@ int ksmbd_override_fsids(struct ksmbd_work *work) ...@@ -775,6 +775,11 @@ int ksmbd_override_fsids(struct ksmbd_work *work)
return 0; return 0;
} }
int ksmbd_override_fsids(struct ksmbd_work *work)
{
return __ksmbd_override_fsids(work, work->tcon->share_conf);
}
void ksmbd_revert_fsids(struct ksmbd_work *work) void ksmbd_revert_fsids(struct ksmbd_work *work)
{ {
const struct cred *cred; const struct cred *cred;
......
...@@ -447,6 +447,8 @@ int ksmbd_extract_shortname(struct ksmbd_conn *conn, ...@@ -447,6 +447,8 @@ int ksmbd_extract_shortname(struct ksmbd_conn *conn,
int ksmbd_smb_negotiate_common(struct ksmbd_work *work, unsigned int command); int ksmbd_smb_negotiate_common(struct ksmbd_work *work, unsigned int command);
int ksmbd_smb_check_shared_mode(struct file *filp, struct ksmbd_file *curr_fp); int ksmbd_smb_check_shared_mode(struct file *filp, struct ksmbd_file *curr_fp);
int __ksmbd_override_fsids(struct ksmbd_work *work,
struct ksmbd_share_config *share);
int ksmbd_override_fsids(struct ksmbd_work *work); int ksmbd_override_fsids(struct ksmbd_work *work);
void ksmbd_revert_fsids(struct ksmbd_work *work); void ksmbd_revert_fsids(struct ksmbd_work *work);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment