ksmbd: prevent out-of-bounds reads in share config responses
PATCH 1/1 ksmbd: prevent out-of-bounds reads in share config responses
[ Upstream commit f25e93768fcc5d8287e50b1ec52a42e4c276df34 ]
Validate IPC share configuration payload sizes before consuming variable-length fields. Bound veto list parsing and account for the separator byte when deriving the path length.
--- fs/ksmbd/mgmt/share_config.c | 38 ++++++++++++++++++++++++++---------- fs/ksmbd/transport_ipc.c | 24 +++++++++++++++++------ 2 files changed, 46 insertions(+), 16 deletions(-)
fs/ksmbd/mgmt/share_config.c +28 -10
@@ -87,9 +87,9 @@ static struct ksmbd_share_config *__share_lookup(const char *name)static int parse_veto_list (struct ksmbd_share_config *share,char *veto_list, -int veto_list_sz) +size_t veto_list_sz) { -int sz =0 ; +size_t sz;if (!veto_list_sz)return 0 ;
@@ -97,7 +97,7 @@ static int parse_veto_list(struct ksmbd_share_config *share,while (veto_list_sz >0 ) {struct ksmbd_veto_pattern *p; - sz =strlen (veto_list); + sz =strnlen (veto_list, veto_list_sz);if (!sz)break ;
@@ -105,7 +105,7 @@ static int parse_veto_list(struct ksmbd_share_config *share,if (!p)return -ENOMEM ; - p->pattern =kstrdup (veto_list,GFP_KERNEL ); + p->pattern =kstrndup (veto_list, sz,GFP_KERNEL );if (!p->pattern) {kfree (p);return -ENOMEM ;
@@ -113,6 +113,9 @@ static int parse_veto_list(struct ksmbd_share_config *share,list_add (&p->list, &share->veto_list); +if (sz == veto_list_sz) +break ; + veto_list += sz +1 ; veto_list_sz -= (sz +1 ); }
@@ -158,13 +161,27 @@ static struct ksmbd_share_config *share_config_request(struct unicode_map *um, share->name =kstrdup (name,GFP_KERNEL );if (!test_share_config_flag (share,KSMBD_SHARE_FLAG_PIPE )) { -int path_len =PATH_MAX ; +size_t path_len; -if (resp->payload_sz) +if (resp->payload_sz <= resp->veto_list_sz) { + ret = -EINVAL ; + }else { path_len = resp->payload_sz - resp->veto_list_sz; - - share->path =kstrndup (ksmbd_share_config_path (resp), path_len, -GFP_KERNEL ); +if (resp->veto_list_sz) + path_len--; + +if (!path_len) { + ret = -EINVAL ; + }else { + share->path =kstrndup ( +ksmbd_share_config_path (resp), + path_len,GFP_KERNEL ); +if (!share->path) + ret = -ENOMEM ; +else + ret =0 ; + } + }if (share->path) { share->path_sz =strlen (share->path); while (share->path_sz > 1 &&
@@ -177,7 +194,8 @@ static struct ksmbd_share_config *share_config_request(struct unicode_map *um, share->force_directory_mode = resp->force_directory_mode; share->force_uid = resp->force_uid; share->force_gid = resp->force_gid; - ret =parse_veto_list (share, +if (!ret) + ret =parse_veto_list (share,KSMBD_SHARE_CONFIG_VETO_LIST (resp), resp->veto_list_sz);if (!ret && share->path) {
fs/ksmbd/transport_ipc.c +18 -6
@@ -475,13 +475,25 @@ static int ipc_validate_msg(struct ipc_msg_table_entry *entry) }else if (entry->type ==KSMBD_EVENT_SHARE_CONFIG_REQUEST ) {struct ksmbd_share_config_response *resp = entry->response; -if (resp->payload_sz) { -if (resp->payload_sz < resp->veto_list_sz) -return -EINVAL ; +if (entry->msg_sz <sizeof (struct ksmbd_share_config_response )) +return -EINVAL ; + +if (strnlen (resp->share_name,sizeof (resp->share_name)) == +sizeof (resp->share_name)) +return -EINVAL ; + +if (resp->veto_list_sz > resp->payload_sz) +return -EINVAL ; + +if (resp->flags !=KSMBD_SHARE_FLAG_INVALID && + !(resp->flags &KSMBD_SHARE_FLAG_PIPE ) && + resp->payload_sz <= resp->veto_list_sz) +return -EINVAL ; + +if (check_add_overflow (sizeof (struct ksmbd_share_config_response ), + resp->payload_sz, &msg_sz)) +return -EINVAL ; - msg_sz =sizeof (struct ksmbd_share_config_response ) + - resp->payload_sz; - } }return entry->msg_sz != msg_sz ? -EINVAL :0 ;
Signature · 1 line
2.34.1
PATCH 1/1 ksmbd: prevent out-of-bounds reads in share config responses
[ Upstream commit f25e93768fcc5d8287e50b1ec52a42e4c276df34 ]
Validate IPC share configuration payload sizes before consuming variable-length fields. Bound veto list parsing and account for the separator byte when deriving the path length.
--- fs/smb/server/mgmt/share_config.c | 38 +++++++++++++++++++++++-------- fs/smb/server/transport_ipc.c | 21 +++++++++++------ 2 files changed, 42 insertions(+), 17 deletions(-)
fs/smb/server/mgmt/share_config.c +28 -10
@@ -88,9 +88,9 @@ static struct ksmbd_share_config *__share_lookup(const char *name)static int parse_veto_list (struct ksmbd_share_config *share,char *veto_list, -int veto_list_sz) +size_t veto_list_sz) { -int sz =0 ; +size_t sz;if (!veto_list_sz)return 0 ;
@@ -98,7 +98,7 @@ static int parse_veto_list(struct ksmbd_share_config *share,while (veto_list_sz >0 ) {struct ksmbd_veto_pattern *p; - sz =strlen (veto_list); + sz =strnlen (veto_list, veto_list_sz);if (!sz)break ;
@@ -106,7 +106,7 @@ static int parse_veto_list(struct ksmbd_share_config *share,if (!p)return -ENOMEM ; - p->pattern =kstrdup (veto_list,KSMBD_DEFAULT_GFP ); + p->pattern =kstrndup (veto_list, sz,KSMBD_DEFAULT_GFP );if (!p->pattern) {kfree (p);return -ENOMEM ;
@@ -114,6 +114,9 @@ static int parse_veto_list(struct ksmbd_share_config *share,list_add (&p->list, &share->veto_list); +if (sz == veto_list_sz) +break ; + veto_list += sz +1 ; veto_list_sz -= (sz +1 ); }
@@ -165,13 +168,27 @@ static struct ksmbd_share_config *share_config_request(struct ksmbd_work *work, }if (!test_share_config_flag (share,KSMBD_SHARE_FLAG_PIPE )) { -int path_len =PATH_MAX ; +size_t path_len; -if (resp->payload_sz) +if (resp->payload_sz <= resp->veto_list_sz) { + ret = -EINVAL ; + }else { path_len = resp->payload_sz - resp->veto_list_sz; - - share->path =kstrndup (ksmbd_share_config_path (resp), path_len, -KSMBD_DEFAULT_GFP ); +if (resp->veto_list_sz) + path_len--; + +if (!path_len) { + ret = -EINVAL ; + }else { + share->path =kstrndup ( +ksmbd_share_config_path (resp), + path_len,KSMBD_DEFAULT_GFP ); +if (!share->path) + ret = -ENOMEM ; +else + ret =0 ; + } + }if (share->path) { share->path_sz =strlen (share->path); while (share->path_sz > 1 &&
@@ -184,7 +201,8 @@ static struct ksmbd_share_config *share_config_request(struct ksmbd_work *work, share->force_directory_mode = resp->force_directory_mode; share->force_uid = resp->force_uid; share->force_gid = resp->force_gid; - ret =parse_veto_list (share, +if (!ret) + ret =parse_veto_list (share,KSMBD_SHARE_CONFIG_VETO_LIST (resp), resp->veto_list_sz);if (!ret && share->path) {
fs/smb/server/transport_ipc.c +14 -7
@@ -524,14 +524,21 @@ static int ipc_validate_msg(struct ipc_msg_table_entry *entry)if (entry->msg_sz <sizeof (struct ksmbd_share_config_response ))return -EINVAL ; -if (resp->payload_sz) { -if (resp->payload_sz < resp->veto_list_sz) -return -EINVAL ; +if (strnlen (resp->share_name,sizeof (resp->share_name)) == +sizeof (resp->share_name)) +return -EINVAL ; -if (check_add_overflow (sizeof (struct ksmbd_share_config_response ), - resp->payload_sz, &msg_sz)) -return -EINVAL ; - } +if (resp->veto_list_sz > resp->payload_sz) +return -EINVAL ; + +if (resp->flags !=KSMBD_SHARE_FLAG_INVALID && + !(resp->flags &KSMBD_SHARE_FLAG_PIPE ) && + resp->payload_sz <= resp->veto_list_sz) +return -EINVAL ; + +if (check_add_overflow (sizeof (struct ksmbd_share_config_response ), + resp->payload_sz, &msg_sz)) +return -EINVAL ;break ; }case KSMBD_EVENT_LOGIN_REQUEST_EXT :
Signature · 1 line
2.34.1
PATCH 1/1 ksmbd: prevent out-of-bounds reads in share config responses
In reply to Namjae Jeon[ Upstream commit f25e93768fcc5d8287e50b1ec52a42e4c276df34 ]
Validate IPC share configuration payload sizes before consuming variable-length fields. Bound veto list parsing and account for the separator byte when deriving the path length.
--- fs/smb/server/mgmt/share_config.c | 38 +++++++++++++++++++++++-------- fs/smb/server/transport_ipc.c | 21 +++++++++++------ 2 files changed, 42 insertions(+), 17 deletions(-)
fs/smb/server/mgmt/share_config.c +28 -10
@@ -88,9 +88,9 @@ static struct ksmbd_share_config *__share_lookup(const char *name)static int parse_veto_list (struct ksmbd_share_config *share,char *veto_list, -int veto_list_sz) +size_t veto_list_sz) { -int sz =0 ; +size_t sz;if (!veto_list_sz)return 0 ;
@@ -98,7 +98,7 @@ static int parse_veto_list(struct ksmbd_share_config *share,while (veto_list_sz >0 ) {struct ksmbd_veto_pattern *p; - sz =strlen (veto_list); + sz =strnlen (veto_list, veto_list_sz);if (!sz)break ;
@@ -106,7 +106,7 @@ static int parse_veto_list(struct ksmbd_share_config *share,if (!p)return -ENOMEM ; - p->pattern =kstrdup (veto_list,KSMBD_DEFAULT_GFP ); + p->pattern =kstrndup (veto_list, sz,KSMBD_DEFAULT_GFP );if (!p->pattern) {kfree (p);return -ENOMEM ;
@@ -114,6 +114,9 @@ static int parse_veto_list(struct ksmbd_share_config *share,list_add (&p->list, &share->veto_list); +if (sz == veto_list_sz) +break ; + veto_list += sz +1 ; veto_list_sz -= (sz +1 ); }
@@ -165,13 +168,27 @@ static struct ksmbd_share_config *share_config_request(struct ksmbd_work *work, }if (!test_share_config_flag (share,KSMBD_SHARE_FLAG_PIPE )) { -int path_len =PATH_MAX ; +size_t path_len; -if (resp->payload_sz) +if (resp->payload_sz <= resp->veto_list_sz) { + ret = -EINVAL ; + }else { path_len = resp->payload_sz - resp->veto_list_sz; - - share->path =kstrndup (ksmbd_share_config_path (resp), path_len, -KSMBD_DEFAULT_GFP ); +if (resp->veto_list_sz) + path_len--; + +if (!path_len) { + ret = -EINVAL ; + }else { + share->path =kstrndup ( +ksmbd_share_config_path (resp), + path_len,KSMBD_DEFAULT_GFP ); +if (!share->path) + ret = -ENOMEM ; +else + ret =0 ; + } + }if (share->path) { share->path_sz =strlen (share->path); while (share->path_sz > 1 &&
@@ -184,7 +201,8 @@ static struct ksmbd_share_config *share_config_request(struct ksmbd_work *work, share->force_directory_mode = resp->force_directory_mode; share->force_uid = resp->force_uid; share->force_gid = resp->force_gid; - ret =parse_veto_list (share, +if (!ret) + ret =parse_veto_list (share,KSMBD_SHARE_CONFIG_VETO_LIST (resp), resp->veto_list_sz);if (!ret && share->path) {
fs/smb/server/transport_ipc.c +14 -7
@@ -524,14 +524,21 @@ static int ipc_validate_msg(struct ipc_msg_table_entry *entry)if (entry->msg_sz <sizeof (struct ksmbd_share_config_response ))return -EINVAL ; -if (resp->payload_sz) { -if (resp->payload_sz < resp->veto_list_sz) -return -EINVAL ; +if (strnlen (resp->share_name,sizeof (resp->share_name)) == +sizeof (resp->share_name)) +return -EINVAL ; -if (check_add_overflow (sizeof (struct ksmbd_share_config_response ), - resp->payload_sz, &msg_sz)) -return -EINVAL ; - } +if (resp->veto_list_sz > resp->payload_sz) +return -EINVAL ; + +if (resp->flags !=KSMBD_SHARE_FLAG_INVALID && + !(resp->flags &KSMBD_SHARE_FLAG_PIPE ) && + resp->payload_sz <= resp->veto_list_sz) +return -EINVAL ; + +if (check_add_overflow (sizeof (struct ksmbd_share_config_response ), + resp->payload_sz, &msg_sz)) +return -EINVAL ;break ; }case KSMBD_EVENT_LOGIN_REQUEST_EXT :
Signature · 1 line
2.34.1
PATCH 1/1 ksmbd: prevent out-of-bounds reads in share config responses
In reply to Namjae Jeon[ Upstream commit f25e93768fcc5d8287e50b1ec52a42e4c276df34 ]
Validate IPC share configuration payload sizes before consuming variable-length fields. Bound veto list parsing and account for the separator byte when deriving the path length.
--- fs/smb/server/mgmt/share_config.c | 38 +++++++++++++++++++++++-------- fs/smb/server/transport_ipc.c | 24 ++++++++++++++----- 2 files changed, 46 insertions(+), 16 deletions(-)
fs/smb/server/mgmt/share_config.c +28 -10
@@ -88,9 +88,9 @@ static struct ksmbd_share_config *__share_lookup(const char *name)static int parse_veto_list (struct ksmbd_share_config *share,char *veto_list, -int veto_list_sz) +size_t veto_list_sz) { -int sz =0 ; +size_t sz;if (!veto_list_sz)return 0 ;
@@ -98,7 +98,7 @@ static int parse_veto_list(struct ksmbd_share_config *share,while (veto_list_sz >0 ) {struct ksmbd_veto_pattern *p; - sz =strlen (veto_list); + sz =strnlen (veto_list, veto_list_sz);if (!sz)break ;
@@ -106,7 +106,7 @@ static int parse_veto_list(struct ksmbd_share_config *share,if (!p)return -ENOMEM ; - p->pattern =kstrdup (veto_list,GFP_KERNEL ); + p->pattern =kstrndup (veto_list, sz,GFP_KERNEL );if (!p->pattern) {kfree (p);return -ENOMEM ;
@@ -114,6 +114,9 @@ static int parse_veto_list(struct ksmbd_share_config *share,list_add (&p->list, &share->veto_list); +if (sz == veto_list_sz) +break ; + veto_list += sz +1 ; veto_list_sz -= (sz +1 ); }
@@ -160,13 +163,27 @@ static struct ksmbd_share_config *share_config_request(struct ksmbd_work *work, share->name =kstrdup (name,GFP_KERNEL );if (!test_share_config_flag (share,KSMBD_SHARE_FLAG_PIPE )) { -int path_len =PATH_MAX ; +size_t path_len; -if (resp->payload_sz) +if (resp->payload_sz <= resp->veto_list_sz) { + ret = -EINVAL ; + }else { path_len = resp->payload_sz - resp->veto_list_sz; - - share->path =kstrndup (ksmbd_share_config_path (resp), path_len, -GFP_KERNEL ); +if (resp->veto_list_sz) + path_len--; + +if (!path_len) { + ret = -EINVAL ; + }else { + share->path =kstrndup ( +ksmbd_share_config_path (resp), + path_len,GFP_KERNEL ); +if (!share->path) + ret = -ENOMEM ; +else + ret =0 ; + } + }if (share->path) { share->path_sz =strlen (share->path); while (share->path_sz > 1 &&
@@ -179,7 +196,8 @@ static struct ksmbd_share_config *share_config_request(struct ksmbd_work *work, share->force_directory_mode = resp->force_directory_mode; share->force_uid = resp->force_uid; share->force_gid = resp->force_gid; - ret =parse_veto_list (share, +if (!ret) + ret =parse_veto_list (share,KSMBD_SHARE_CONFIG_VETO_LIST (resp), resp->veto_list_sz);if (!ret && share->path) {
fs/smb/server/transport_ipc.c +18 -6
@@ -487,13 +487,25 @@ static int ipc_validate_msg(struct ipc_msg_table_entry *entry) }else if (entry->type ==KSMBD_EVENT_SHARE_CONFIG_REQUEST ) {struct ksmbd_share_config_response *resp = entry->response; -if (resp->payload_sz) { -if (resp->payload_sz < resp->veto_list_sz) -return -EINVAL ; +if (entry->msg_sz <sizeof (struct ksmbd_share_config_response )) +return -EINVAL ; + +if (strnlen (resp->share_name,sizeof (resp->share_name)) == +sizeof (resp->share_name)) +return -EINVAL ; + +if (resp->veto_list_sz > resp->payload_sz) +return -EINVAL ; + +if (resp->flags !=KSMBD_SHARE_FLAG_INVALID && + !(resp->flags &KSMBD_SHARE_FLAG_PIPE ) && + resp->payload_sz <= resp->veto_list_sz) +return -EINVAL ; + +if (check_add_overflow (sizeof (struct ksmbd_share_config_response ), + resp->payload_sz, &msg_sz)) +return -EINVAL ; - msg_sz =sizeof (struct ksmbd_share_config_response ) + - resp->payload_sz; - } }return entry->msg_sz != msg_sz ? -EINVAL :0 ;
Signature · 1 line
2.34.1
PATCH 1/1 ksmbd: prevent out-of-bounds reads in share config responses
In reply to Namjae Jeon[ Upstream commit f25e93768fcc5d8287e50b1ec52a42e4c276df34 ]
Validate IPC share configuration payload sizes before consuming variable-length fields. Bound veto list parsing and account for the separator byte when deriving the path length.
--- fs/smb/server/mgmt/share_config.c | 38 +++++++++++++++++++++++-------- fs/smb/server/transport_ipc.c | 21 +++++++++++------ 2 files changed, 42 insertions(+), 17 deletions(-)
fs/smb/server/mgmt/share_config.c +28 -10
@@ -88,9 +88,9 @@ static struct ksmbd_share_config *__share_lookup(const char *name)static int parse_veto_list (struct ksmbd_share_config *share,char *veto_list, -int veto_list_sz) +size_t veto_list_sz) { -int sz =0 ; +size_t sz;if (!veto_list_sz)return 0 ;
@@ -98,7 +98,7 @@ static int parse_veto_list(struct ksmbd_share_config *share,while (veto_list_sz >0 ) {struct ksmbd_veto_pattern *p; - sz =strlen (veto_list); + sz =strnlen (veto_list, veto_list_sz);if (!sz)break ;
@@ -106,7 +106,7 @@ static int parse_veto_list(struct ksmbd_share_config *share,if (!p)return -ENOMEM ; - p->pattern =kstrdup (veto_list,GFP_KERNEL ); + p->pattern =kstrndup (veto_list, sz,GFP_KERNEL );if (!p->pattern) {kfree (p);return -ENOMEM ;
@@ -114,6 +114,9 @@ static int parse_veto_list(struct ksmbd_share_config *share,list_add (&p->list, &share->veto_list); +if (sz == veto_list_sz) +break ; + veto_list += sz +1 ; veto_list_sz -= (sz +1 ); }
@@ -160,13 +163,27 @@ static struct ksmbd_share_config *share_config_request(struct ksmbd_work *work, share->name =kstrdup (name,GFP_KERNEL );if (!test_share_config_flag (share,KSMBD_SHARE_FLAG_PIPE )) { -int path_len =PATH_MAX ; +size_t path_len; -if (resp->payload_sz) +if (resp->payload_sz <= resp->veto_list_sz) { + ret = -EINVAL ; + }else { path_len = resp->payload_sz - resp->veto_list_sz; - - share->path =kstrndup (ksmbd_share_config_path (resp), path_len, -GFP_KERNEL ); +if (resp->veto_list_sz) + path_len--; + +if (!path_len) { + ret = -EINVAL ; + }else { + share->path =kstrndup ( +ksmbd_share_config_path (resp), + path_len,GFP_KERNEL ); +if (!share->path) + ret = -ENOMEM ; +else + ret =0 ; + } + }if (share->path) { share->path_sz =strlen (share->path); while (share->path_sz > 1 &&
@@ -179,7 +196,8 @@ static struct ksmbd_share_config *share_config_request(struct ksmbd_work *work, share->force_directory_mode = resp->force_directory_mode; share->force_uid = resp->force_uid; share->force_gid = resp->force_gid; - ret =parse_veto_list (share, +if (!ret) + ret =parse_veto_list (share,KSMBD_SHARE_CONFIG_VETO_LIST (resp), resp->veto_list_sz);if (!ret && share->path) {
fs/smb/server/transport_ipc.c +14 -7
@@ -524,14 +524,21 @@ static int ipc_validate_msg(struct ipc_msg_table_entry *entry)if (entry->msg_sz <sizeof (struct ksmbd_share_config_response ))return -EINVAL ; -if (resp->payload_sz) { -if (resp->payload_sz < resp->veto_list_sz) -return -EINVAL ; +if (strnlen (resp->share_name,sizeof (resp->share_name)) == +sizeof (resp->share_name)) +return -EINVAL ; -if (check_add_overflow (sizeof (struct ksmbd_share_config_response ), - resp->payload_sz, &msg_sz)) -return -EINVAL ; - } +if (resp->veto_list_sz > resp->payload_sz) +return -EINVAL ; + +if (resp->flags !=KSMBD_SHARE_FLAG_INVALID && + !(resp->flags &KSMBD_SHARE_FLAG_PIPE ) && + resp->payload_sz <= resp->veto_list_sz) +return -EINVAL ; + +if (check_add_overflow (sizeof (struct ksmbd_share_config_response ), + resp->payload_sz, &msg_sz)) +return -EINVAL ;break ; }case KSMBD_EVENT_LOGIN_REQUEST_EXT :
Signature · 1 line
2.34.1
PATCH 1/1 ksmbd: prevent out-of-bounds reads in share config responses
In reply to Namjae Jeon[ Upstream commit f25e93768fcc5d8287e50b1ec52a42e4c276df34 ]
Validate IPC share configuration payload sizes before consuming variable-length fields. Bound veto list parsing and account for the separator byte when deriving the path length.
--- fs/smb/server/mgmt/share_config.c | 40 +++++++++++++++++++++---------- fs/smb/server/transport_ipc.c | 24 +++++++++++++------ 2 files changed, 44 insertions(+), 20 deletions(-)
fs/smb/server/mgmt/share_config.c +27 -13
@@ -88,9 +88,9 @@ static struct ksmbd_share_config *__share_lookup(const char *name)static int parse_veto_list (struct ksmbd_share_config *share,char *veto_list, -int veto_list_sz) +size_t veto_list_sz) { -int sz =0 ; +size_t sz;if (!veto_list_sz)return 0 ;
@@ -98,7 +98,7 @@ static int parse_veto_list(struct ksmbd_share_config *share,while (veto_list_sz >0 ) {struct ksmbd_veto_pattern *p; - sz =strlen (veto_list); + sz =strnlen (veto_list, veto_list_sz);if (!sz)break ;
@@ -106,7 +106,7 @@ static int parse_veto_list(struct ksmbd_share_config *share,if (!p)return -ENOMEM ; - p->pattern =kstrdup (veto_list,KSMBD_DEFAULT_GFP ); + p->pattern =kstrndup (veto_list, sz,KSMBD_DEFAULT_GFP );if (!p->pattern) {kfree (p);return -ENOMEM ;
@@ -114,6 +114,9 @@ static int parse_veto_list(struct ksmbd_share_config *share,list_add (&p->list, &share->veto_list); +if (sz == veto_list_sz) +break ; + veto_list += sz +1 ; veto_list_sz -= (sz +1 ); }
@@ -160,17 +163,28 @@ static struct ksmbd_share_config *share_config_request(struct ksmbd_work *work, share->name =kstrdup (name,KSMBD_DEFAULT_GFP );if (!test_share_config_flag (share,KSMBD_SHARE_FLAG_PIPE )) { -int path_len =PATH_MAX ; - -if (resp->payload_sz) - path_len = resp->payload_sz - resp->veto_list_sz; +size_t path_len; - share->path =kstrndup (ksmbd_share_config_path (resp), path_len, -KSMBD_DEFAULT_GFP ); -if (!share->path) { - ret = -ENOMEM ; +if (resp->payload_sz <= resp->veto_list_sz) { + ret = -EINVAL ; }else { - ret =0 ; + path_len = resp->payload_sz - resp->veto_list_sz; +if (resp->veto_list_sz) + path_len--; + +if (!path_len) { + ret = -EINVAL ; + }else { + share->path =kstrndup ( +ksmbd_share_config_path (resp), + path_len,KSMBD_DEFAULT_GFP ); +if (!share->path) + ret = -ENOMEM ; +else + ret =0 ; + } + } +if (share->path) { share->path_sz =strlen (share->path);while (share->path_sz >1 && share->path[share->path_sz -1 ] =='/' )
fs/smb/server/transport_ipc.c +17 -7
@@ -514,14 +514,24 @@ static int ipc_validate_msg(struct ipc_msg_table_entry *entry) {struct ksmbd_share_config_response *resp = entry->response; -if (resp->payload_sz) { -if (resp->payload_sz < resp->veto_list_sz) -return -EINVAL ; +if (entry->msg_sz <sizeof (struct ksmbd_share_config_response )) +return -EINVAL ; -if (check_add_overflow (sizeof (struct ksmbd_share_config_response ), - resp->payload_sz, &msg_sz)) -return -EINVAL ; - } +if (strnlen (resp->share_name,sizeof (resp->share_name)) == +sizeof (resp->share_name)) +return -EINVAL ; + +if (resp->veto_list_sz > resp->payload_sz) +return -EINVAL ; + +if (resp->flags !=KSMBD_SHARE_FLAG_INVALID && + !(resp->flags &KSMBD_SHARE_FLAG_PIPE ) && + resp->payload_sz <= resp->veto_list_sz) +return -EINVAL ; + +if (check_add_overflow (sizeof (struct ksmbd_share_config_response ), + resp->payload_sz, &msg_sz)) +return -EINVAL ;break ; }case KSMBD_EVENT_LOGIN_REQUEST_EXT :
Signature · 1 line
2.34.1
Quoted 3 lines
Validate IPC share configuration payload sizes before consuming variable-length fields. Bound veto list parsing and account for the separator byte when deriving the path length.
Queued for 6.18, 6.12, 6.6, 6.1 and 5.15, thanks.
Signature · 2 lines
Thanks, Sasha