Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
L
linux
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Kirill Smelkov
linux
Commits
c9d75268
Commit
c9d75268
authored
Feb 18, 2002
by
Alexander Viro
Committed by
Linus Torvalds
Feb 18, 2002
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
[PATCH] (4/4) 2.5.5-pre1 fixes
Fixes overflow checks in smb_encode_path().
parent
edd97fd7
Changes
1
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
47 additions
and
34 deletions
+47
-34
fs/smbfs/proc.c
fs/smbfs/proc.c
+47
-34
No files found.
fs/smbfs/proc.c
View file @
c9d75268
...
@@ -103,6 +103,8 @@ static int convert_memcpy(char *output, int olen,
...
@@ -103,6 +103,8 @@ static int convert_memcpy(char *output, int olen,
struct
nls_table
*
nls_from
,
struct
nls_table
*
nls_from
,
struct
nls_table
*
nls_to
)
struct
nls_table
*
nls_to
)
{
{
if
(
olen
<
ilen
)
return
-
ENAMETOOLONG
;
memcpy
(
output
,
input
,
ilen
);
memcpy
(
output
,
input
,
ilen
);
return
ilen
;
return
ilen
;
}
}
...
@@ -126,20 +128,21 @@ static int convert_cp(char *output, int olen,
...
@@ -126,20 +128,21 @@ static int convert_cp(char *output, int olen,
/* convert by changing to unicode and back to the new cp */
/* convert by changing to unicode and back to the new cp */
n
=
nls_from
->
char2uni
((
unsigned
char
*
)
input
,
ilen
,
&
ch
);
n
=
nls_from
->
char2uni
((
unsigned
char
*
)
input
,
ilen
,
&
ch
);
if
(
n
<
0
)
if
(
n
<
0
)
goto
out
;
goto
fail
;
input
+=
n
;
input
+=
n
;
ilen
-=
n
;
ilen
-=
n
;
n
=
nls_to
->
uni2char
(
ch
,
output
,
olen
);
n
=
nls_to
->
uni2char
(
ch
,
output
,
olen
);
if
(
n
<
0
)
if
(
n
<
0
)
goto
out
;
goto
fail
;
output
+=
n
;
output
+=
n
;
olen
-=
n
;
olen
-=
n
;
len
+=
n
;
len
+=
n
;
}
}
out:
return
len
;
return
len
;
fail:
return
n
;
}
}
static
int
setcodepage
(
struct
nls_table
**
p
,
char
*
name
)
static
int
setcodepage
(
struct
nls_table
**
p
,
char
*
name
)
...
@@ -214,71 +217,79 @@ smb_encode_smb_length(__u8 * p, __u32 len)
...
@@ -214,71 +217,79 @@ smb_encode_smb_length(__u8 * p, __u32 len)
* smb_build_path: build the path to entry and name storing it in buf.
* smb_build_path: build the path to entry and name storing it in buf.
* The path returned will have the trailing '\0'.
* The path returned will have the trailing '\0'.
*/
*/
static
int
smb_build_path
(
struct
smb_sb_info
*
server
,
char
*
buf
,
static
int
smb_build_path
(
struct
smb_sb_info
*
server
,
char
*
buf
,
int
maxlen
,
struct
dentry
*
entry
,
struct
qstr
*
name
)
struct
dentry
*
entry
,
struct
qstr
*
name
)
{
{
char
*
path
=
buf
;
char
*
path
=
buf
;
int
len
;
int
len
;
if
(
maxlen
<
2
)
return
-
ENAMETOOLONG
;
if
(
maxlen
>
SMB_MAXNAMELEN
+
1
)
maxlen
=
SMB_MAXNAMELEN
+
1
;
if
(
entry
==
NULL
)
if
(
entry
==
NULL
)
goto
test_name_and_out
;
goto
test_name_and_out
;
/*
/*
* If IS_ROOT, we have to do no walking at all.
* If IS_ROOT, we have to do no walking at all.
*/
*/
if
(
IS_ROOT
(
entry
))
{
if
(
IS_ROOT
(
entry
)
&&
!
name
)
{
*
(
path
++
)
=
'\\'
;
*
path
++
=
'\\'
;
if
(
name
!=
NULL
)
*
path
++
=
'\0'
;
goto
name_and_out
;
return
2
;
goto
out
;
}
}
/*
/*
* Build the path string walking the tree backward from end to ROOT
* Build the path string walking the tree backward from end to ROOT
* and store it in reversed order [see reverse_string()]
* and store it in reversed order [see reverse_string()]
*/
*/
for
(;;)
{
while
(
!
IS_ROOT
(
entry
))
{
if
(
entry
->
d_name
.
len
>
SMB_MAXNAMELEN
)
if
(
maxlen
<
3
)
return
-
ENAMETOOLONG
;
if
(
path
-
buf
+
entry
->
d_name
.
len
>
SMB_MAXPATHLEN
)
return
-
ENAMETOOLONG
;
return
-
ENAMETOOLONG
;
len
=
server
->
convert
(
path
,
SMB_MAXNAMELEN
,
len
=
server
->
convert
(
path
,
maxlen
-
2
,
entry
->
d_name
.
name
,
entry
->
d_name
.
len
,
entry
->
d_name
.
name
,
entry
->
d_name
.
len
,
server
->
local_nls
,
server
->
remote_nls
);
server
->
local_nls
,
server
->
remote_nls
);
if
(
len
<
0
)
return
len
;
reverse_string
(
path
,
len
);
reverse_string
(
path
,
len
);
path
+=
len
;
path
+=
len
;
*
path
++
=
'\\'
;
*
(
path
++
)
=
'\\'
;
maxlen
-=
len
+
1
;
entry
=
entry
->
d_parent
;
entry
=
entry
->
d_parent
;
if
(
IS_ROOT
(
entry
))
if
(
IS_ROOT
(
entry
))
break
;
break
;
}
}
reverse_string
(
buf
,
path
-
buf
);
reverse_string
(
buf
,
path
-
buf
);
/* maxlen is at least 1 */
test_name_and_out:
test_name_and_out:
if
(
name
!=
NULL
)
{
if
(
name
)
{
*
(
path
++
)
=
'\\'
;
if
(
maxlen
<
3
)
name_and_out:
return
-
ENAMETOOLONG
;
len
=
server
->
convert
(
path
,
SMB_MAXNAMELEN
,
*
path
++
=
'\\'
;
len
=
server
->
convert
(
path
,
maxlen
-
2
,
name
->
name
,
name
->
len
,
name
->
name
,
name
->
len
,
server
->
local_nls
,
server
->
remote_nls
);
server
->
local_nls
,
server
->
remote_nls
);
if
(
len
<
0
)
return
len
;
path
+=
len
;
path
+=
len
;
maxlen
-=
len
+
1
;
}
}
out:
/* maxlen is at least 1 */
*
(
path
++
)
=
'\0'
;
*
path
++
=
'\0'
;
return
(
path
-
buf
)
;
return
path
-
buf
;
}
}
static
int
smb_encode_path
(
struct
smb_sb_info
*
server
,
char
*
buf
,
static
int
smb_encode_path
(
struct
smb_sb_info
*
server
,
char
*
buf
,
int
maxlen
,
struct
dentry
*
dir
,
struct
qstr
*
name
)
struct
dentry
*
dir
,
struct
qstr
*
name
)
{
{
int
result
;
int
result
;
result
=
smb_build_path
(
server
,
buf
,
dir
,
name
);
result
=
smb_build_path
(
server
,
buf
,
maxlen
,
dir
,
name
);
if
(
result
<
0
)
if
(
result
<
0
)
goto
out
;
goto
out
;
if
(
server
->
opt
.
protocol
<=
SMB_PROTOCOL_COREPLUS
)
if
(
server
->
opt
.
protocol
<=
SMB_PROTOCOL_COREPLUS
)
...
@@ -292,9 +303,12 @@ static int smb_simple_encode_path(struct smb_sb_info *server, char **p,
...
@@ -292,9 +303,12 @@ static int smb_simple_encode_path(struct smb_sb_info *server, char **p,
{
{
char
*
s
=
*
p
;
char
*
s
=
*
p
;
int
res
;
int
res
;
int
maxlen
=
((
char
*
)
server
->
packet
+
server
->
packet_size
)
-
s
;
if
(
!
maxlen
)
return
-
ENAMETOOLONG
;
*
s
++
=
4
;
*
s
++
=
4
;
res
=
smb_encode_path
(
server
,
s
,
entry
,
name
);
res
=
smb_encode_path
(
server
,
s
,
maxlen
-
1
,
entry
,
name
);
if
(
res
<
0
)
if
(
res
<
0
)
return
res
;
return
res
;
*
p
=
s
+
res
;
*
p
=
s
+
res
;
...
@@ -1588,8 +1602,7 @@ smb_proc_readdir_short(struct file *filp, void *dirent, filldir_t filldir,
...
@@ -1588,8 +1602,7 @@ smb_proc_readdir_short(struct file *filp, void *dirent, filldir_t filldir,
struct
smb_sb_info
*
server
=
server_from_dentry
(
dir
);
struct
smb_sb_info
*
server
=
server_from_dentry
(
dir
);
struct
qstr
qname
;
struct
qstr
qname
;
struct
smb_fattr
fattr
;
struct
smb_fattr
fattr
;
char
*
p
;
unsigned
char
*
p
;
int
result
;
int
result
;
int
i
,
first
,
entries_seen
,
entries
;
int
i
,
first
,
entries_seen
,
entries
;
int
entries_asked
=
(
server
->
opt
.
max_xmit
-
100
)
/
SMB_DIRINFO_SIZE
;
int
entries_asked
=
(
server
->
opt
.
max_xmit
-
100
)
/
SMB_DIRINFO_SIZE
;
...
@@ -1859,7 +1872,7 @@ smb_proc_readdir_long(struct file *filp, void *dirent, filldir_t filldir,
...
@@ -1859,7 +1872,7 @@ smb_proc_readdir_long(struct file *filp, void *dirent, filldir_t filldir,
*/
*/
mask
=
param
+
12
;
mask
=
param
+
12
;
mask_len
=
smb_encode_path
(
server
,
mask
,
dir
,
&
star
);
mask_len
=
smb_encode_path
(
server
,
mask
,
SMB_MAXNAMELEN
+
1
,
dir
,
&
star
);
if
(
mask_len
<
0
)
{
if
(
mask_len
<
0
)
{
result
=
mask_len
;
result
=
mask_len
;
goto
unlock_return
;
goto
unlock_return
;
...
@@ -2066,7 +2079,7 @@ smb_proc_getattr_ff(struct smb_sb_info *server, struct dentry *dentry,
...
@@ -2066,7 +2079,7 @@ smb_proc_getattr_ff(struct smb_sb_info *server, struct dentry *dentry,
int
mask_len
,
result
;
int
mask_len
,
result
;
retry:
retry:
mask_len
=
smb_encode_path
(
server
,
mask
,
dentry
,
NULL
);
mask_len
=
smb_encode_path
(
server
,
mask
,
SMB_MAXNAMELEN
+
1
,
dentry
,
NULL
);
if
(
mask_len
<
0
)
{
if
(
mask_len
<
0
)
{
result
=
mask_len
;
result
=
mask_len
;
goto
out
;
goto
out
;
...
@@ -2192,7 +2205,7 @@ smb_proc_getattr_trans2(struct smb_sb_info *server, struct dentry *dir,
...
@@ -2192,7 +2205,7 @@ smb_proc_getattr_trans2(struct smb_sb_info *server, struct dentry *dir,
retry:
retry:
WSET
(
param
,
0
,
1
);
/* Info level SMB_INFO_STANDARD */
WSET
(
param
,
0
,
1
);
/* Info level SMB_INFO_STANDARD */
DSET
(
param
,
2
,
0
);
DSET
(
param
,
2
,
0
);
result
=
smb_encode_path
(
server
,
param
+
6
,
dir
,
NULL
);
result
=
smb_encode_path
(
server
,
param
+
6
,
SMB_MAXNAMELEN
+
1
,
dir
,
NULL
);
if
(
result
<
0
)
if
(
result
<
0
)
goto
out
;
goto
out
;
p
=
param
+
6
+
result
;
p
=
param
+
6
+
result
;
...
@@ -2438,7 +2451,7 @@ smb_proc_setattr_trans2(struct smb_sb_info *server,
...
@@ -2438,7 +2451,7 @@ smb_proc_setattr_trans2(struct smb_sb_info *server,
retry:
retry:
WSET
(
param
,
0
,
1
);
/* Info level SMB_INFO_STANDARD */
WSET
(
param
,
0
,
1
);
/* Info level SMB_INFO_STANDARD */
DSET
(
param
,
2
,
0
);
DSET
(
param
,
2
,
0
);
result
=
smb_encode_path
(
server
,
param
+
6
,
dir
,
NULL
);
result
=
smb_encode_path
(
server
,
param
+
6
,
SMB_MAXNAMELEN
+
1
,
dir
,
NULL
);
if
(
result
<
0
)
if
(
result
<
0
)
goto
out
;
goto
out
;
p
=
param
+
6
+
result
;
p
=
param
+
6
+
result
;
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment