ksmbd: browse interfaces list on FSCTL_QUERY_INTERFACE_INFO IOCTL
[ Upstream commit b2d99376c5d61eb60ffdb6c503e4b6c8f9712ddd ] ksmbd.mount will give each interfaces list and bind_interfaces_only flags to ksmbd server. Previously, the interfaces list was sent only when bind_interfaces_only was enabled. ksmbd server browse only interfaces list given from ksmbd.conf on FSCTL_QUERY_INTERFACE_INFO IOCTL. Signed-off-by: Namjae Jeon <linkinjeon@kernel.org> Signed-off-by: Steve French <stfrench@microsoft.com> Stable-dep-of: 21a4e47578d4 ("ksmbd: fix use-after-free in __smb2_lease_break_noti()") Signed-off-by: Sasha Levin <sashal@kernel.org>
This commit is contained in:
committed by
Greg Kroah-Hartman
parent
8d2c1acc88
commit
0fc403192d
@@ -111,7 +111,8 @@ struct ksmbd_startup_request {
|
|||||||
__u32 smb2_max_credits; /* MAX credits */
|
__u32 smb2_max_credits; /* MAX credits */
|
||||||
__u32 smbd_max_io_size; /* smbd read write size */
|
__u32 smbd_max_io_size; /* smbd read write size */
|
||||||
__u32 max_connections; /* Number of maximum simultaneous connections */
|
__u32 max_connections; /* Number of maximum simultaneous connections */
|
||||||
__u32 reserved[126]; /* Reserved room */
|
__s8 bind_interfaces_only;
|
||||||
|
__s8 reserved[503]; /* Reserved room */
|
||||||
__u32 ifc_list_sz; /* interfaces list size */
|
__u32 ifc_list_sz; /* interfaces list size */
|
||||||
__s8 ____payload[];
|
__s8 ____payload[];
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -46,6 +46,7 @@ struct ksmbd_server_config {
|
|||||||
|
|
||||||
char *conf[SERVER_CONF_WORK_GROUP + 1];
|
char *conf[SERVER_CONF_WORK_GROUP + 1];
|
||||||
struct task_struct *dh_task;
|
struct task_struct *dh_task;
|
||||||
|
bool bind_interfaces_only;
|
||||||
};
|
};
|
||||||
|
|
||||||
extern struct ksmbd_server_config server_conf;
|
extern struct ksmbd_server_config server_conf;
|
||||||
|
|||||||
@@ -38,6 +38,7 @@
|
|||||||
#include "mgmt/user_session.h"
|
#include "mgmt/user_session.h"
|
||||||
#include "mgmt/ksmbd_ida.h"
|
#include "mgmt/ksmbd_ida.h"
|
||||||
#include "ndr.h"
|
#include "ndr.h"
|
||||||
|
#include "transport_tcp.h"
|
||||||
|
|
||||||
static void __wbuf(struct ksmbd_work *work, void **req, void **rsp)
|
static void __wbuf(struct ksmbd_work *work, void **req, void **rsp)
|
||||||
{
|
{
|
||||||
@@ -7771,6 +7772,9 @@ static int fsctl_query_iface_info_ioctl(struct ksmbd_conn *conn,
|
|||||||
if (netdev->type == ARPHRD_LOOPBACK)
|
if (netdev->type == ARPHRD_LOOPBACK)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
if (!ksmbd_find_netdev_name_iface_list(netdev->name))
|
||||||
|
continue;
|
||||||
|
|
||||||
flags = dev_get_flags(netdev);
|
flags = dev_get_flags(netdev);
|
||||||
if (!(flags & IFF_RUNNING))
|
if (!(flags & IFF_RUNNING))
|
||||||
continue;
|
continue;
|
||||||
|
|||||||
@@ -338,6 +338,7 @@ static int ipc_server_config_on_startup(struct ksmbd_startup_request *req)
|
|||||||
ret = ksmbd_set_netbios_name(req->netbios_name);
|
ret = ksmbd_set_netbios_name(req->netbios_name);
|
||||||
ret |= ksmbd_set_server_string(req->server_string);
|
ret |= ksmbd_set_server_string(req->server_string);
|
||||||
ret |= ksmbd_set_work_group(req->work_group);
|
ret |= ksmbd_set_work_group(req->work_group);
|
||||||
|
server_conf.bind_interfaces_only = req->bind_interfaces_only;
|
||||||
ret |= ksmbd_tcp_set_interfaces(KSMBD_STARTUP_CONFIG_INTERFACES(req),
|
ret |= ksmbd_tcp_set_interfaces(KSMBD_STARTUP_CONFIG_INTERFACES(req),
|
||||||
req->ifc_list_sz);
|
req->ifc_list_sz);
|
||||||
out:
|
out:
|
||||||
|
|||||||
@@ -504,32 +504,37 @@ out_clear:
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct interface *ksmbd_find_netdev_name_iface_list(char *netdev_name)
|
||||||
|
{
|
||||||
|
struct interface *iface;
|
||||||
|
|
||||||
|
list_for_each_entry(iface, &iface_list, entry)
|
||||||
|
if (!strcmp(iface->name, netdev_name))
|
||||||
|
return iface;
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
static int ksmbd_netdev_event(struct notifier_block *nb, unsigned long event,
|
static int ksmbd_netdev_event(struct notifier_block *nb, unsigned long event,
|
||||||
void *ptr)
|
void *ptr)
|
||||||
{
|
{
|
||||||
struct net_device *netdev = netdev_notifier_info_to_dev(ptr);
|
struct net_device *netdev = netdev_notifier_info_to_dev(ptr);
|
||||||
struct interface *iface;
|
struct interface *iface;
|
||||||
int ret, found = 0;
|
int ret;
|
||||||
|
|
||||||
switch (event) {
|
switch (event) {
|
||||||
case NETDEV_UP:
|
case NETDEV_UP:
|
||||||
if (netif_is_bridge_port(netdev))
|
if (netif_is_bridge_port(netdev))
|
||||||
return NOTIFY_OK;
|
return NOTIFY_OK;
|
||||||
|
|
||||||
list_for_each_entry(iface, &iface_list, entry) {
|
iface = ksmbd_find_netdev_name_iface_list(netdev->name);
|
||||||
if (!strcmp(iface->name, netdev->name)) {
|
if (iface && iface->state == IFACE_STATE_DOWN) {
|
||||||
found = 1;
|
ksmbd_debug(CONN, "netdev-up event: netdev(%s) is going up\n",
|
||||||
if (iface->state != IFACE_STATE_DOWN)
|
iface->name);
|
||||||
break;
|
ret = create_socket(iface);
|
||||||
ksmbd_debug(CONN, "netdev-up event: netdev(%s) is going up\n",
|
if (ret)
|
||||||
iface->name);
|
return NOTIFY_OK;
|
||||||
ret = create_socket(iface);
|
|
||||||
if (ret)
|
|
||||||
return NOTIFY_OK;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
if (!found && bind_additional_ifaces) {
|
if (!iface && bind_additional_ifaces) {
|
||||||
iface = alloc_iface(kstrdup(netdev->name, KSMBD_DEFAULT_GFP));
|
iface = alloc_iface(kstrdup(netdev->name, KSMBD_DEFAULT_GFP));
|
||||||
if (!iface)
|
if (!iface)
|
||||||
return NOTIFY_OK;
|
return NOTIFY_OK;
|
||||||
@@ -541,21 +546,19 @@ static int ksmbd_netdev_event(struct notifier_block *nb, unsigned long event,
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case NETDEV_DOWN:
|
case NETDEV_DOWN:
|
||||||
list_for_each_entry(iface, &iface_list, entry) {
|
iface = ksmbd_find_netdev_name_iface_list(netdev->name);
|
||||||
if (!strcmp(iface->name, netdev->name) &&
|
if (iface && iface->state == IFACE_STATE_CONFIGURED) {
|
||||||
iface->state == IFACE_STATE_CONFIGURED) {
|
ksmbd_debug(CONN, "netdev-down event: netdev(%s) is going down\n",
|
||||||
ksmbd_debug(CONN, "netdev-down event: netdev(%s) is going down\n",
|
iface->name);
|
||||||
iface->name);
|
tcp_stop_kthread(iface->ksmbd_kthread);
|
||||||
tcp_stop_kthread(iface->ksmbd_kthread);
|
iface->ksmbd_kthread = NULL;
|
||||||
iface->ksmbd_kthread = NULL;
|
mutex_lock(&iface->sock_release_lock);
|
||||||
mutex_lock(&iface->sock_release_lock);
|
tcp_destroy_socket(iface->ksmbd_socket);
|
||||||
tcp_destroy_socket(iface->ksmbd_socket);
|
iface->ksmbd_socket = NULL;
|
||||||
iface->ksmbd_socket = NULL;
|
mutex_unlock(&iface->sock_release_lock);
|
||||||
mutex_unlock(&iface->sock_release_lock);
|
|
||||||
|
|
||||||
iface->state = IFACE_STATE_DOWN;
|
iface->state = IFACE_STATE_DOWN;
|
||||||
break;
|
break;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -624,18 +627,6 @@ int ksmbd_tcp_set_interfaces(char *ifc_list, int ifc_list_sz)
|
|||||||
int sz = 0;
|
int sz = 0;
|
||||||
|
|
||||||
if (!ifc_list_sz) {
|
if (!ifc_list_sz) {
|
||||||
struct net_device *netdev;
|
|
||||||
|
|
||||||
rtnl_lock();
|
|
||||||
for_each_netdev(&init_net, netdev) {
|
|
||||||
if (netif_is_bridge_port(netdev))
|
|
||||||
continue;
|
|
||||||
if (!alloc_iface(kstrdup(netdev->name, KSMBD_DEFAULT_GFP))) {
|
|
||||||
rtnl_unlock();
|
|
||||||
return -ENOMEM;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
rtnl_unlock();
|
|
||||||
bind_additional_ifaces = 1;
|
bind_additional_ifaces = 1;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,6 +7,7 @@
|
|||||||
#define __KSMBD_TRANSPORT_TCP_H__
|
#define __KSMBD_TRANSPORT_TCP_H__
|
||||||
|
|
||||||
int ksmbd_tcp_set_interfaces(char *ifc_list, int ifc_list_sz);
|
int ksmbd_tcp_set_interfaces(char *ifc_list, int ifc_list_sz);
|
||||||
|
struct interface *ksmbd_find_netdev_name_iface_list(char *netdev_name);
|
||||||
int ksmbd_tcp_init(void);
|
int ksmbd_tcp_init(void);
|
||||||
void ksmbd_tcp_destroy(void);
|
void ksmbd_tcp_destroy(void);
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user