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
b6a823e7
Commit
b6a823e7
authored
Nov 23, 2007
by
Linus Torvalds
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Import 2.0.2
parent
a96e1f22
Changes
28
Hide whitespace changes
Inline
Side-by-side
Showing
28 changed files
with
499 additions
and
328 deletions
+499
-328
CREDITS
CREDITS
+7
-0
Documentation/Changes
Documentation/Changes
+3
-1
Makefile
Makefile
+1
-1
arch/alpha/config.in
arch/alpha/config.in
+9
-0
arch/alpha/defconfig
arch/alpha/defconfig
+5
-0
drivers/char/serial.c
drivers/char/serial.c
+3
-2
drivers/net/lance32.c
drivers/net/lance32.c
+3
-3
fs/exec.c
fs/exec.c
+62
-41
fs/fcntl.c
fs/fcntl.c
+10
-9
fs/open.c
fs/open.c
+52
-31
fs/pipe.c
fs/pipe.c
+49
-36
fs/select.c
fs/select.c
+89
-47
fs/smbfs/proc.c
fs/smbfs/proc.c
+33
-7
include/asm-alpha/errno.h
include/asm-alpha/errno.h
+3
-3
include/asm-alpha/posix_types.h
include/asm-alpha/posix_types.h
+4
-4
include/asm-i386/errno.h
include/asm-i386/errno.h
+3
-3
include/linux/fs.h
include/linux/fs.h
+2
-0
include/linux/in.h
include/linux/in.h
+1
-1
include/linux/posix_types.h
include/linux/posix_types.h
+5
-5
include/linux/sched.h
include/linux/sched.h
+3
-5
include/net/tcp.h
include/net/tcp.h
+0
-16
kernel/exit.c
kernel/exit.c
+21
-8
kernel/fork.c
kernel/fork.c
+20
-9
net/ipv4/af_inet.c
net/ipv4/af_inet.c
+1
-1
net/ipv4/tcp.c
net/ipv4/tcp.c
+47
-7
net/ipv4/tcp_input.c
net/ipv4/tcp_input.c
+20
-4
net/socket.c
net/socket.c
+17
-22
net/unix/af_unix.c
net/unix/af_unix.c
+26
-62
No files found.
CREDITS
View file @
b6a823e7
...
...
@@ -1029,6 +1029,13 @@ S: RR #5, 497 Pole Line Road
S: Thunder Bay, Ontario
S: CANADA P7C 5M9
N: Yuri Per
E: yuri@pts.mipt.ru
D: Some smbfs fixes
S: Demonstratsii 8-382
S: Tula 300000
S: Russia
N: Kai Petzke
E: wpp@marie.physik.tu-berlin.de
W: http://physik.tu-berlin.de/~wpp
...
...
Documentation/Changes
View file @
b6a823e7
...
...
@@ -179,7 +179,9 @@ or earlier, you will probably get a weird error on shutdown in which
your computer shuts down fine but "INIT: error reading initrequest" or
words to that effect scroll across your screen hundreds of times. To
fix, upgrade to
ftp://ftp.cistron.nl/pub/people/miquels/debian/sysvinit-2.62.tar.gz.
ftp://sunsite.unc.edu/pub/Linux/system/Daemons/init/sysvinit-2.64.tar.gz or
ftp://tsx-11.mit.edu /pub/linux/sources/sbin/sysvinit-2.64.tar.gz
If you're trying to run NCSA httpd, you have to set pre-spawning of
daemons to zero, as it incorrectly assumes SunOS behavior. I recommend
...
...
Makefile
View file @
b6a823e7
VERSION
=
2
PATCHLEVEL
=
0
SUBLEVEL
=
1
SUBLEVEL
=
2
ARCH
=
i386
...
...
arch/alpha/config.in
View file @
b6a823e7
...
...
@@ -122,6 +122,15 @@ if [ "$CONFIG_NET" = "y" ]; then
endmenu
fi
mainmenu_option next_comment
comment 'ISDN subsystem'
tristate 'ISDN support' CONFIG_ISDN
if [ "$CONFIG_ISDN" != "n" ]; then
source drivers/isdn/Config.in
fi
endmenu
mainmenu_option next_comment
comment 'CD-ROM drivers (not for SCSI or IDE/ATAPI drives)'
...
...
arch/alpha/defconfig
View file @
b6a823e7
...
...
@@ -161,6 +161,11 @@ CONFIG_DE4X5=y
# CONFIG_TR is not set
# CONFIG_ARCNET is not set
#
# ISDN subsystem
#
# CONFIG_ISDN is not set
#
# CD-ROM drivers (not for SCSI or IDE/ATAPI drives)
#
...
...
drivers/char/serial.c
View file @
b6a823e7
...
...
@@ -2755,8 +2755,9 @@ int rs_init(void)
serial_driver
.
type
=
TTY_DRIVER_TYPE_SERIAL
;
serial_driver
.
subtype
=
SERIAL_TYPE_NORMAL
;
serial_driver
.
init_termios
=
tty_std_termios
;
serial_driver
.
init_termios
.
c_lflag
&=~
(
ISIG
|
ICANON
|
ECHO
);
serial_driver
.
flags
=
TTY_DRIVER_REAL_RAW
|
TTY_DRIVER_RESET_TERMIOS
;
serial_driver
.
init_termios
.
c_cflag
=
B9600
|
CS8
|
CREAD
|
HUPCL
|
CLOCAL
;
serial_driver
.
flags
=
TTY_DRIVER_REAL_RAW
;
serial_driver
.
refcount
=
&
serial_refcount
;
serial_driver
.
table
=
serial_table
;
serial_driver
.
termios
=
serial_termios
;
...
...
drivers/net/lance32.c
View file @
b6a823e7
...
...
@@ -789,8 +789,8 @@ static struct enet_statistics *
lance32_get_stats
(
struct
device
*
dev
)
{
struct
lance32_private
*
lp
=
(
struct
lance32_private
*
)
dev
->
priv
;
shor
t
ioaddr
=
dev
->
base_addr
;
short
saved_addr
;
in
t
ioaddr
=
dev
->
base_addr
;
unsigned
short
saved_addr
;
unsigned
long
flags
;
save_flags
(
flags
);
...
...
@@ -809,7 +809,7 @@ lance32_get_stats(struct device *dev)
static
void
lance32_set_multicast_list
(
struct
device
*
dev
)
{
shor
t
ioaddr
=
dev
->
base_addr
;
in
t
ioaddr
=
dev
->
base_addr
;
struct
lance32_private
*
lp
=
(
struct
lance32_private
*
)
dev
->
priv
;
if
(
dev
->
flags
&
IFF_PROMISC
)
{
...
...
fs/exec.c
View file @
b6a823e7
...
...
@@ -114,41 +114,34 @@ int unregister_binfmt(struct linux_binfmt * fmt)
int
open_inode
(
struct
inode
*
inode
,
int
mode
)
{
int
error
,
fd
;
struct
file
*
f
,
**
fpp
;
int
fd
;
if
(
!
inode
->
i_op
||
!
inode
->
i_op
->
default_file_ops
)
return
-
EINVAL
;
f
=
get_empty_filp
();
if
(
!
f
)
return
-
ENFILE
;
fd
=
0
;
fpp
=
current
->
files
->
fd
;
for
(;;)
{
if
(
!*
fpp
)
break
;
if
(
++
fd
>=
NR_OPEN
)
{
f
->
f_count
--
;
return
-
EMFILE
;
fd
=
get_unused_fd
();
if
(
fd
>=
0
)
{
struct
file
*
f
=
get_empty_filp
();
if
(
!
f
)
{
put_unused_fd
(
fd
);
return
-
ENFILE
;
}
fpp
++
;
}
*
fpp
=
f
;
f
->
f_flags
=
mode
;
f
->
f_mode
=
(
mode
+
1
)
&
O_ACCMODE
;
f
->
f_inode
=
inode
;
f
->
f_pos
=
0
;
f
->
f_reada
=
0
;
f
->
f_op
=
inode
->
i_op
->
default_file_ops
;
if
(
f
->
f_op
->
open
)
{
error
=
f
->
f_op
->
open
(
inode
,
f
);
if
(
error
)
{
*
fpp
=
NULL
;
f
->
f_count
--
;
return
error
;
f
->
f_flags
=
mode
;
f
->
f_mode
=
(
mode
+
1
)
&
O_ACCMODE
;
f
->
f_inode
=
inode
;
f
->
f_pos
=
0
;
f
->
f_reada
=
0
;
f
->
f_op
=
inode
->
i_op
->
default_file_ops
;
if
(
f
->
f_op
->
open
)
{
int
error
=
f
->
f_op
->
open
(
inode
,
f
);
if
(
error
)
{
f
->
f_count
--
;
put_unused_fd
(
fd
);
return
error
;
}
}
current
->
files
->
fd
[
fd
]
=
f
;
inode
->
i_count
++
;
}
inode
->
i_count
++
;
return
fd
;
}
...
...
@@ -399,10 +392,45 @@ static void exec_mmap(void)
}
/*
* Th
is function flushes out all traces of the currently running executable so
* that a new one can be started
* Th
ese functions flushes out all traces of the currently running executable
*
so
that a new one can be started
*/
static
inline
void
flush_old_signals
(
struct
signal_struct
*
sig
)
{
int
i
;
struct
sigaction
*
sa
=
sig
->
action
;
for
(
i
=
32
;
i
!=
0
;
i
--
)
{
sa
->
sa_mask
=
0
;
sa
->
sa_flags
=
0
;
if
(
sa
->
sa_handler
!=
SIG_IGN
)
sa
->
sa_handler
=
NULL
;
sa
++
;
}
}
static
inline
void
flush_old_files
(
struct
files_struct
*
files
)
{
unsigned
long
j
;
j
=
0
;
for
(;;)
{
unsigned
long
set
,
i
;
i
=
j
*
__NFDBITS
;
if
(
i
>=
NR_OPEN
)
break
;
set
=
files
->
close_on_exec
.
fds_bits
[
j
];
files
->
close_on_exec
.
fds_bits
[
j
]
=
0
;
j
++
;
for
(
;
set
;
i
++
,
set
>>=
1
)
{
if
(
set
&
1
)
sys_close
(
i
);
}
}
}
void
flush_old_exec
(
struct
linux_binprm
*
bprm
)
{
int
i
;
...
...
@@ -429,16 +457,9 @@ void flush_old_exec(struct linux_binprm * bprm)
if
(
bprm
->
e_uid
!=
current
->
euid
||
bprm
->
e_gid
!=
current
->
egid
||
permission
(
bprm
->
inode
,
MAY_READ
))
current
->
dumpable
=
0
;
for
(
i
=
0
;
i
<
32
;
i
++
)
{
current
->
sig
->
action
[
i
].
sa_mask
=
0
;
current
->
sig
->
action
[
i
].
sa_flags
=
0
;
if
(
current
->
sig
->
action
[
i
].
sa_handler
!=
SIG_IGN
)
current
->
sig
->
action
[
i
].
sa_handler
=
NULL
;
}
for
(
i
=
0
;
i
<
NR_OPEN
;
i
++
)
if
(
FD_ISSET
(
i
,
&
current
->
files
->
close_on_exec
))
sys_close
(
i
);
FD_ZERO
(
&
current
->
files
->
close_on_exec
);
flush_old_signals
(
current
->
sig
);
flush_old_files
(
current
->
files
);
}
/*
...
...
fs/fcntl.c
View file @
b6a823e7
...
...
@@ -13,23 +13,24 @@
#include <linux/fcntl.h>
#include <linux/string.h>
#include <asm/bitops.h>
extern
int
sock_fcntl
(
struct
file
*
,
unsigned
int
cmd
,
unsigned
long
arg
);
static
inline
int
dupfd
(
unsigned
int
fd
,
unsigned
int
arg
)
{
if
(
fd
>=
NR_OPEN
||
!
current
->
files
->
fd
[
fd
])
struct
files_struct
*
files
=
current
->
files
;
if
(
fd
>=
NR_OPEN
||
!
files
->
fd
[
fd
])
return
-
EBADF
;
if
(
arg
>=
NR_OPEN
)
return
-
EINVAL
;
while
(
arg
<
NR_OPEN
)
if
(
current
->
files
->
fd
[
arg
])
arg
++
;
else
break
;
if
(
arg
>=
NR_OPEN
)
arg
=
find_next_zero_bit
(
&
files
->
open_fds
,
NR_OPEN
,
arg
);
if
(
arg
>=
current
->
rlim
[
RLIMIT_NOFILE
].
rlim_cur
)
return
-
EMFILE
;
FD_CLR
(
arg
,
&
current
->
files
->
close_on_exec
);
(
current
->
files
->
fd
[
arg
]
=
current
->
files
->
fd
[
fd
])
->
f_count
++
;
FD_SET
(
arg
,
&
files
->
open_fds
);
FD_CLR
(
arg
,
&
files
->
close_on_exec
);
(
files
->
fd
[
arg
]
=
files
->
fd
[
fd
])
->
f_count
++
;
return
arg
;
}
...
...
fs/open.c
View file @
b6a823e7
...
...
@@ -19,6 +19,7 @@
#include <linux/mm.h>
#include <asm/segment.h>
#include <asm/bitops.h>
asmlinkage
int
sys_statfs
(
const
char
*
path
,
struct
statfs
*
buf
)
{
...
...
@@ -496,11 +497,11 @@ asmlinkage int sys_chown(const char * filename, uid_t user, gid_t group)
* for the internal routines (ie open_namei()/follow_link() etc). 00 is
* used by symlinks.
*/
int
do_open
(
const
char
*
filename
,
int
flags
,
int
mode
)
static
int
do_open
(
const
char
*
filename
,
int
flags
,
int
mode
,
int
fd
)
{
struct
inode
*
inode
;
struct
file
*
f
;
int
flag
,
error
,
fd
;
int
flag
,
error
;
f
=
get_empty_filp
();
if
(
!
f
)
...
...
@@ -533,21 +534,9 @@ int do_open(const char * filename,int flags,int mode)
}
f
->
f_flags
&=
~
(
O_CREAT
|
O_EXCL
|
O_NOCTTY
|
O_TRUNC
);
/*
* We have to do this last, because we mustn't export
* an incomplete fd to other processes which may share
* the same file table with us.
*/
for
(
fd
=
0
;
fd
<
NR_OPEN
&&
fd
<
current
->
rlim
[
RLIMIT_NOFILE
].
rlim_cur
;
fd
++
)
{
if
(
!
current
->
files
->
fd
[
fd
])
{
current
->
files
->
fd
[
fd
]
=
f
;
FD_CLR
(
fd
,
&
current
->
files
->
close_on_exec
);
return
fd
;
}
}
error
=
-
EMFILE
;
if
(
f
->
f_op
&&
f
->
f_op
->
release
)
f
->
f_op
->
release
(
inode
,
f
);
current
->
files
->
fd
[
fd
]
=
f
;
return
0
;
cleanup_all:
if
(
f
->
f_mode
&
FMODE_WRITE
)
put_write_access
(
inode
);
...
...
@@ -558,16 +547,44 @@ int do_open(const char * filename,int flags,int mode)
return
error
;
}
/*
* Find a empty file descriptor entry, and mark it busy
*/
int
get_unused_fd
(
void
)
{
int
fd
;
struct
files_struct
*
files
=
current
->
files
;
fd
=
find_first_zero_bit
(
&
files
->
open_fds
,
NR_OPEN
);
if
(
fd
<
current
->
rlim
[
RLIMIT_NOFILE
].
rlim_cur
)
{
FD_SET
(
fd
,
&
files
->
open_fds
);
FD_CLR
(
fd
,
&
files
->
close_on_exec
);
return
fd
;
}
return
-
EMFILE
;
}
inline
void
put_unused_fd
(
int
fd
)
{
FD_CLR
(
fd
,
&
current
->
files
->
open_fds
);
}
asmlinkage
int
sys_open
(
const
char
*
filename
,
int
flags
,
int
mode
)
{
char
*
tmp
;
int
error
;
int
fd
,
error
;
fd
=
get_unused_fd
();
if
(
fd
<
0
)
return
fd
;
error
=
getname
(
filename
,
&
tmp
);
if
(
error
)
return
error
;
error
=
do_open
(
tmp
,
flags
,
mode
);
putname
(
tmp
);
if
(
!
error
)
{
error
=
do_open
(
tmp
,
flags
,
mode
,
fd
);
putname
(
tmp
);
if
(
!
error
)
return
fd
;
}
put_unused_fd
(
fd
);
return
error
;
}
...
...
@@ -610,16 +627,20 @@ int close_fp(struct file *filp)
}
asmlinkage
int
sys_close
(
unsigned
int
fd
)
{
{
int
error
;
struct
file
*
filp
;
if
(
fd
>=
NR_OPEN
)
return
-
EBADF
;
FD_CLR
(
fd
,
&
current
->
files
->
close_on_exec
);
if
(
!
(
filp
=
current
->
files
->
fd
[
fd
]))
return
-
EBADF
;
current
->
files
->
fd
[
fd
]
=
NULL
;
return
(
close_fp
(
filp
));
struct
files_struct
*
files
;
files
=
current
->
files
;
error
=
-
EBADF
;
if
(
fd
<
NR_OPEN
&&
(
filp
=
files
->
fd
[
fd
])
!=
NULL
)
{
put_unused_fd
(
fd
);
FD_CLR
(
fd
,
&
files
->
close_on_exec
);
files
->
fd
[
fd
]
=
NULL
;
error
=
close_fp
(
filp
);
}
return
error
;
}
/*
...
...
fs/pipe.c
View file @
b6a823e7
...
...
@@ -414,45 +414,58 @@ struct inode_operations pipe_inode_operations = {
int
do_pipe
(
int
*
fd
)
{
struct
inode
*
inode
;
struct
file
*
f
[
2
];
struct
file
*
f1
,
*
f2
;
int
error
;
int
i
,
j
;
error
=
ENFILE
;
f1
=
get_empty_filp
();
if
(
!
f1
)
goto
no_files
;
f2
=
get_empty_filp
();
if
(
!
f2
)
goto
close_f1
;
inode
=
get_pipe_inode
();
if
(
!
inode
)
return
-
ENFILE
;
for
(
j
=
0
;
j
<
2
;
j
++
)
if
(
!
(
f
[
j
]
=
get_empty_filp
()))
break
;
if
(
j
<
2
)
{
iput
(
inode
);
iput
(
inode
);
if
(
j
)
f
[
0
]
->
f_count
--
;
return
-
ENFILE
;
}
j
=
0
;
for
(
i
=
0
;
j
<
2
&&
i
<
NR_OPEN
&&
i
<
current
->
rlim
[
RLIMIT_NOFILE
].
rlim_cur
;
i
++
)
if
(
!
current
->
files
->
fd
[
i
])
{
current
->
files
->
fd
[
fd
[
j
]
=
i
]
=
f
[
j
];
j
++
;
}
if
(
j
<
2
)
{
iput
(
inode
);
iput
(
inode
);
f
[
0
]
->
f_count
--
;
f
[
1
]
->
f_count
--
;
if
(
j
)
current
->
files
->
fd
[
fd
[
0
]]
=
NULL
;
return
-
EMFILE
;
}
f
[
0
]
->
f_inode
=
f
[
1
]
->
f_inode
=
inode
;
f
[
0
]
->
f_pos
=
f
[
1
]
->
f_pos
=
0
;
f
[
0
]
->
f_flags
=
O_RDONLY
;
f
[
0
]
->
f_op
=
&
read_pipe_fops
;
f
[
0
]
->
f_mode
=
1
;
/* read */
f
[
1
]
->
f_flags
=
O_WRONLY
;
f
[
1
]
->
f_op
=
&
write_pipe_fops
;
f
[
1
]
->
f_mode
=
2
;
/* write */
goto
close_f12
;
error
=
get_unused_fd
();
if
(
error
<
0
)
goto
close_f12_inode
;
i
=
error
;
error
=
get_unused_fd
();
if
(
error
<
0
)
goto
close_f12_inode_i
;
j
=
error
;
f1
->
f_inode
=
f2
->
f_inode
=
inode
;
/* read file */
f1
->
f_pos
=
f2
->
f_pos
=
0
;
f1
->
f_flags
=
O_RDONLY
;
f1
->
f_op
=
&
read_pipe_fops
;
f1
->
f_mode
=
1
;
/* write file */
f2
->
f_flags
=
O_WRONLY
;
f2
->
f_op
=
&
write_pipe_fops
;
f2
->
f_mode
=
2
;
current
->
files
->
fd
[
i
]
=
f1
;
current
->
files
->
fd
[
j
]
=
f2
;
fd
[
0
]
=
i
;
fd
[
1
]
=
j
;
return
0
;
close_f12_inode_i:
put_unused_fd
(
i
);
close_f12_inode:
inode
->
i_count
--
;
iput
(
inode
);
close_f12:
f2
->
f_count
--
;
close_f1:
f1
->
f_count
--
;
no_files:
return
error
;
}
fs/select.c
View file @
b6a823e7
...
...
@@ -92,11 +92,13 @@ static int do_select(int n, fd_set *in, fd_set *out, fd_set *ex,
int
i
,
j
;
int
max
=
-
1
;
for
(
j
=
0
;
j
<
__FDSET_INTS
;
j
++
)
{
j
=
0
;
for
(;;)
{
i
=
j
*
__NFDBITS
;
if
(
i
>=
n
)
break
;
set
=
in
->
fds_bits
[
j
]
|
out
->
fds_bits
[
j
]
|
ex
->
fds_bits
[
j
];
j
++
;
for
(
;
set
;
i
++
,
set
>>=
1
)
{
if
(
i
>=
n
)
goto
end_check
;
...
...
@@ -113,9 +115,6 @@ static int do_select(int n, fd_set *in, fd_set *out, fd_set *ex,
n
=
max
+
1
;
if
(
!
(
entry
=
(
struct
select_table_entry
*
)
__get_free_page
(
GFP_KERNEL
)))
return
-
ENOMEM
;
FD_ZERO
(
res_in
);
FD_ZERO
(
res_out
);
FD_ZERO
(
res_ex
);
count
=
0
;
wait_table
.
nr
=
0
;
wait_table
.
entry
=
entry
;
...
...
@@ -153,51 +152,79 @@ static int do_select(int n, fd_set *in, fd_set *out, fd_set *ex,
/*
* We do a VERIFY_WRITE here even though we are only reading this time:
* we'll write to it eventually..
*
* Use "int" accesses to let user-mode fd_set's be int-aligned.
*/
static
int
__get_fd_set
(
int
nr
,
unsigned
int
*
fs_pointer
,
fd_se
t
*
fdset
)
static
int
__get_fd_set
(
unsigned
long
nr
,
int
*
fs_pointer
,
in
t
*
fdset
)
{
int
error
,
i
;
unsigned
int
*
tmp
;
FD_ZERO
(
fdset
);
if
(
!
fs_pointer
)
return
0
;
error
=
verify_area
(
VERIFY_WRITE
,
fs_pointer
,
sizeof
(
fd_set
));
if
(
error
)
/* round up nr to nearest "int" */
nr
=
(
nr
+
8
*
sizeof
(
int
)
-
1
)
/
(
8
*
sizeof
(
int
));
if
(
fs_pointer
)
{
int
error
=
verify_area
(
VERIFY_WRITE
,
fs_pointer
,
nr
*
sizeof
(
int
));
if
(
!
error
)
{
while
(
nr
)
{
*
fdset
=
get_user
(
fs_pointer
);
nr
--
;
fs_pointer
++
;
fdset
++
;
}
}
return
error
;
tmp
=
fdset
->
fds_bits
;
for
(
i
=
__FDSET_INTS
;
i
>
0
;
i
--
)
{
if
(
nr
<=
0
)
break
;
*
tmp
=
get_user
(
fs_pointer
);
tmp
++
;
fs_pointer
++
;
nr
-=
8
*
sizeof
(
unsigned
int
);
}
while
(
nr
)
{
*
fdset
=
0
;
nr
--
;
fdset
++
;
}
return
0
;
}
static
void
__set_fd_set
(
int
nr
,
unsigned
int
*
fs_pointer
,
unsigned
int
*
fdset
)
static
void
__set_fd_set
(
long
nr
,
int
*
fs_pointer
,
int
*
fdset
)
{
int
i
;
if
(
!
fs_pointer
)
return
;
for
(
i
=
__FDSET_INTS
;
i
>
0
;
i
--
)
{
if
(
nr
<=
0
)
break
;
while
(
nr
>=
0
)
{
put_user
(
*
fdset
,
fs_pointer
);
nr
-=
8
*
sizeof
(
int
);
fdset
++
;
fs_pointer
++
;
nr
-=
8
*
sizeof
(
unsigned
int
);
}
}
/* We can do long accesses here, kernel fdsets are always long-aligned */
static
inline
void
__zero_fd_set
(
long
nr
,
unsigned
long
*
fdset
)
{
while
(
nr
>=
0
)
{
*
fdset
=
0
;
nr
-=
8
*
sizeof
(
unsigned
long
);
fdset
++
;
}
}
/*
* Due to kernel stack usage, we use a _limited_ fd_set type here, and once
* we really start supporting >256 file descriptors we'll probably have to
* allocate the kernel fd_set copies dynamically.. (The kernel select routines
* are careful to touch only the defined low bits of any fd_set pointer, this
* is important for performance too).
*
* Note a few subtleties: we use "long" for the dummy, not int, and we do a
* subtract by 1 on the nr of file descriptors. The former is better for
* machines with long > int, and the latter allows us to test the bit count
* against "zero or positive", which can mostly be just a sign bit test..
*/
typedef
struct
{
unsigned
long
dummy
[
NR_OPEN
/
(
8
*
(
sizeof
(
unsigned
long
)))];
}
limited_fd_set
;
#define get_fd_set(nr,fsp,fdp) \
__get_fd_set(nr, (
unsigned int *) (fsp), fdp
)
__get_fd_set(nr, (
int *) (fsp), (int *) (fdp)
)
#define set_fd_set(nr,fsp,fdp) \
__set_fd_set(nr, (unsigned int *) (fsp), (unsigned int *) (fdp))
__set_fd_set((nr)-1, (int *) (fsp), (int *) (fdp))
#define zero_fd_set(nr,fdp) \
__zero_fd_set((nr)-1, (unsigned long *) (fdp))
/*
* We can actually return ERESTARTSYS instead of EINTR, but I'd
...
...
@@ -209,31 +236,41 @@ __set_fd_set(nr, (unsigned int *) (fsp), (unsigned int *) (fdp))
*/
asmlinkage
int
sys_select
(
int
n
,
fd_set
*
inp
,
fd_set
*
outp
,
fd_set
*
exp
,
struct
timeval
*
tvp
)
{
int
i
;
fd_set
res_in
,
in
;
fd_set
res_out
,
out
;
fd_set
res_ex
,
ex
;
int
error
;
limited_
fd_set
res_in
,
in
;
limited_
fd_set
res_out
,
out
;
limited_
fd_set
res_ex
,
ex
;
unsigned
long
timeout
;
error
=
-
EINVAL
;
if
(
n
<
0
)
return
-
EINVAL
;
goto
out
;
if
(
n
>
NR_OPEN
)
n
=
NR_OPEN
;
if
((
i
=
get_fd_set
(
n
,
inp
,
&
in
))
||
(
i
=
get_fd_set
(
n
,
outp
,
&
out
))
||
(
i
=
get_fd_set
(
n
,
exp
,
&
ex
)))
return
i
;
if
((
error
=
get_fd_set
(
n
,
inp
,
&
in
))
||
(
error
=
get_fd_set
(
n
,
outp
,
&
out
))
||
(
error
=
get_fd_set
(
n
,
exp
,
&
ex
)))
goto
out
;
timeout
=
~
0UL
;
if
(
tvp
)
{
i
=
verify_area
(
VERIFY_WRITE
,
tvp
,
sizeof
(
*
tvp
));
if
(
i
)
return
i
;
error
=
verify_area
(
VERIFY_WRITE
,
tvp
,
sizeof
(
*
tvp
));
if
(
error
)
goto
out
;
timeout
=
ROUND_UP
(
get_user
(
&
tvp
->
tv_usec
),(
1000000
/
HZ
));
timeout
+=
get_user
(
&
tvp
->
tv_sec
)
*
(
unsigned
long
)
HZ
;
if
(
timeout
)
timeout
+=
jiffies
+
1
;
}
zero_fd_set
(
n
,
&
res_in
);
zero_fd_set
(
n
,
&
res_out
);
zero_fd_set
(
n
,
&
res_ex
);
current
->
timeout
=
timeout
;
i
=
do_select
(
n
,
&
in
,
&
out
,
&
ex
,
&
res_in
,
&
res_out
,
&
res_ex
);
error
=
do_select
(
n
,
(
fd_set
*
)
&
in
,
(
fd_set
*
)
&
out
,
(
fd_set
*
)
&
ex
,
(
fd_set
*
)
&
res_in
,
(
fd_set
*
)
&
res_out
,
(
fd_set
*
)
&
res_ex
);
timeout
=
current
->
timeout
-
jiffies
-
1
;
current
->
timeout
=
0
;
if
((
long
)
timeout
<
0
)
...
...
@@ -244,12 +281,17 @@ asmlinkage int sys_select(int n, fd_set *inp, fd_set *outp, fd_set *exp, struct
timeout
*=
(
1000000
/
HZ
);
put_user
(
timeout
,
&
tvp
->
tv_usec
);
}
if
(
i
<
0
)
return
i
;
if
(
!
i
&&
(
current
->
signal
&
~
current
->
blocked
))
return
-
ERESTARTNOHAND
;
if
(
error
<
0
)
goto
out
;
if
(
!
error
)
{
error
=
-
ERESTARTNOHAND
;
if
(
current
->
signal
&
~
current
->
blocked
)
goto
out
;
error
=
0
;
}
set_fd_set
(
n
,
inp
,
&
res_in
);
set_fd_set
(
n
,
outp
,
&
res_out
);
set_fd_set
(
n
,
exp
,
&
res_ex
);
return
i
;
out:
return
error
;
}
fs/smbfs/proc.c
View file @
b6a823e7
...
...
@@ -3,6 +3,7 @@
*
* Copyright (C) 1995 by Paal-Kr. Engstad and Volker Lendecke
*
* 28/06/96 - Fixed long file name support (smb_proc_readdir_long) by Yuri Per
*/
#include <linux/config.h>
...
...
@@ -1152,6 +1153,7 @@ smb_proc_readdir_long(struct smb_server *server, struct inode *dir, int fpos,
int
info_level
=
1
;
char
*
p
;
char
*
lastname
;
int
i
;
int
first
,
total_count
;
struct
smb_dirent
*
current_entry
;
...
...
@@ -1171,9 +1173,15 @@ smb_proc_readdir_long(struct smb_server *server, struct inode *dir, int fpos,
int
ff_dir_handle
=
0
;
int
loop_count
=
0
;
int
dirlen
=
strlen
(
SMB_FINFO
(
dir
)
->
path
);
char
mask
[
dirlen
+
5
]
;
int
dirlen
=
strlen
(
SMB_FINFO
(
dir
)
->
path
)
+
3
;
char
*
mask
;
mask
=
smb_kmalloc
(
dirlen
,
GFP_KERNEL
);
if
(
mask
==
NULL
)
{
printk
(
"smb_proc_readdir_long: Memory allocation failed
\n
"
);
return
-
ENOMEM
;
}
strcpy
(
mask
,
SMB_FINFO
(
dir
)
->
path
);
strcat
(
mask
,
"
\\
*"
);
...
...
@@ -1297,22 +1305,37 @@ smb_proc_readdir_long(struct smb_server *server, struct inode *dir, int fpos,
p
=
resp_data
;
/* we might need the lastname for continuations */
lastname
=
""
;
if
(
ff_lastname
>
0
)
{
switch
(
info_level
)
{
case
260
:
ff_resume_key
=
0
;
strcpy
(
mask
,
p
+
ff_lastname
+
94
)
;
lastname
=
p
+
ff_lastname
+
94
;
ff_resume_key
=
0
;
break
;
case
1
:
strcpy
(
mask
,
p
+
ff_lastname
+
1
)
;
lastname
=
p
+
ff_lastname
+
1
;
ff_resume_key
=
0
;
break
;
}
}
else
strcpy
(
mask
,
""
);
/* Increase size of mask, if it is too small */
i
=
strlen
(
lastname
)
+
1
;
if
(
i
>
dirlen
)
{
smb_kfree_s
(
mask
,
0
);
dirlen
=
i
;
mask
=
smb_kmalloc
(
dirlen
,
GFP_KERNEL
);
if
(
mask
==
NULL
)
{
printk
(
"smb_proc_readdir_long: Memory allocation failed
\n
"
);
result
=
-
ENOMEM
;
break
;
}
strcpy
(
mask
,
lastname
);
}
/* Now we are ready to parse smb directory entries. */
...
...
@@ -1355,6 +1378,9 @@ smb_proc_readdir_long(struct smb_server *server, struct inode *dir, int fpos,
}
finished:
if
(
mask
!=
NULL
)
smb_kfree_s
(
mask
,
0
);
if
(
resp_data
!=
NULL
)
{
smb_kfree_s
(
resp_data
,
0
);
resp_data
=
NULL
;
...
...
include/asm-alpha/errno.h
View file @
b6a823e7
...
...
@@ -106,9 +106,9 @@
#define ENOANO 100
/* No anode */
#define EBADRQC 101
/* Invalid request code */
#define EBADSLT 102
/* Invalid slot */
#if 0
#define EDEADLOCK
103 /* File locking deadlock error */
#endif
#define EDEADLOCK
EDEADLK
#define EBFONT 104
/* Bad font file format */
#define ENONET 105
/* Machine is not on the network */
#define ENOLINK 106
/* Link has been severed */
...
...
include/asm-alpha/posix_types.h
View file @
b6a823e7
...
...
@@ -74,18 +74,18 @@ static __inline__ int __FD_ISSET(unsigned long fd, __kernel_fd_set *p)
#undef __FD_ZERO
static
__inline__
void
__FD_ZERO
(
__kernel_fd_set
*
p
)
{
unsigned
int
*
tmp
=
p
->
fds_bits
;
unsigned
long
*
tmp
=
p
->
fds_bits
;
int
i
;
if
(
__builtin_constant_p
(
__FDSET_
INT
S
))
{
switch
(
__FDSET_
INT
S
)
{
if
(
__builtin_constant_p
(
__FDSET_
LONG
S
))
{
switch
(
__FDSET_
LONG
S
)
{
case
8
:
tmp
[
0
]
=
0
;
tmp
[
1
]
=
0
;
tmp
[
2
]
=
0
;
tmp
[
3
]
=
0
;
tmp
[
4
]
=
0
;
tmp
[
5
]
=
0
;
tmp
[
6
]
=
0
;
tmp
[
7
]
=
0
;
return
;
}
}
i
=
__FDSET_
INT
S
;
i
=
__FDSET_
LONG
S
;
while
(
i
)
{
i
--
;
*
tmp
=
0
;
...
...
include/asm-i386/errno.h
View file @
b6a823e7
...
...
@@ -58,9 +58,9 @@
#define ENOANO 55
/* No anode */
#define EBADRQC 56
/* Invalid request code */
#define EBADSLT 57
/* Invalid slot */
#if 0
#define EDEADLOCK
58 /* File locking deadlock error */
#endif
#define EDEADLOCK
EDEADLK
#define EBFONT 59
/* Bad font file format */
#define ENOSTR 60
/* Device not a stream */
#define ENODATA 61
/* No data available */
...
...
include/linux/fs.h
View file @
b6a823e7
...
...
@@ -623,6 +623,8 @@ extern struct inode * get_empty_inode(void);
extern
void
insert_inode_hash
(
struct
inode
*
);
extern
void
clear_inode
(
struct
inode
*
);
extern
struct
inode
*
get_pipe_inode
(
void
);
extern
int
get_unused_fd
(
void
);
extern
void
put_unused_fd
(
int
);
extern
struct
file
*
get_empty_filp
(
void
);
extern
int
close_fp
(
struct
file
*
filp
);
extern
struct
buffer_head
*
get_hash_table
(
kdev_t
dev
,
int
block
,
int
size
);
...
...
include/linux/in.h
View file @
b6a823e7
...
...
@@ -101,7 +101,7 @@ struct sockaddr_in {
#define INADDR_BROADCAST ((unsigned long int) 0xffffffff)
/* Address indicating an error return. */
#define INADDR_NONE
0xffffffff
#define INADDR_NONE
((unsigned long int) 0xffffffff)
/* Network number for local host loopback. */
#define IN_LOOPBACKNET 127
...
...
include/linux/posix_types.h
View file @
b6a823e7
...
...
@@ -27,22 +27,22 @@
* use the ones here.
*/
#undef __NFDBITS
#define __NFDBITS (8 * sizeof(unsigned
int
))
#define __NFDBITS (8 * sizeof(unsigned
long
))
#undef __FD_SETSIZE
#define __FD_SETSIZE 1024
#undef __FDSET_
INT
S
#define __FDSET_
INT
S (__FD_SETSIZE/__NFDBITS)
#undef __FDSET_
LONG
S
#define __FDSET_
LONG
S (__FD_SETSIZE/__NFDBITS)
#undef __FDELT
#define __FDELT(d) ((d) / __NFDBITS)
#undef __FDMASK
#define __FDMASK(d) (1 << ((d) % __NFDBITS))
#define __FDMASK(d) (1
UL
<< ((d) % __NFDBITS))
typedef
struct
{
unsigned
int
fds_bits
[
__FDSET_INT
S
];
unsigned
long
fds_bits
[
__FDSET_LONG
S
];
}
__kernel_fd_set
;
#include <asm/posix_types.h>
...
...
include/linux/sched.h
View file @
b6a823e7
...
...
@@ -108,20 +108,18 @@ extern void trap_init(void);
asmlinkage
void
schedule
(
void
);
/*
???
*/
/*
Open file table structure
*/
struct
files_struct
{
/* ??? */
int
count
;
/* bit mask to close fds on exec */
fd_set
close_on_exec
;
/* do we have at most NR_OPEN available fds? I assume fd i maps into
* each open file */
fd_set
open_fds
;
struct
file
*
fd
[
NR_OPEN
];
};
#define INIT_FILES { \
1, \
{ { 0, } }, \
{ { 0, } }, \
{ NULL, } \
}
...
...
include/net/tcp.h
View file @
b6a823e7
...
...
@@ -174,22 +174,6 @@ extern void tcp_reset_xmit_timer(struct sock *, int, unsigned long);
extern
void
tcp_delack_timer
(
unsigned
long
);
extern
void
tcp_retransmit_timer
(
unsigned
long
);
/*
* Default sequence number picking algorithm.
* As close as possible to RFC 793, which
* suggests using a 250kHz clock.
* Further reading shows this assumes 2MB/s networks.
* For 10MB/s ethernet, a 1MHz clock is appropriate.
* That's funny, Linux has one built in! Use it!
*/
static
inline
u32
tcp_init_seq
(
void
)
{
struct
timeval
tv
;
do_gettimeofday
(
&
tv
);
return
tv
.
tv_usec
+
tv
.
tv_sec
*
1000000
;
}
static
__inline__
int
tcp_old_window
(
struct
sock
*
sk
)
{
return
sk
->
window
-
(
sk
->
acked_seq
-
sk
->
lastwin_seq
);
...
...
kernel/exit.c
View file @
b6a823e7
...
...
@@ -393,6 +393,26 @@ static inline void forget_original_parent(struct task_struct * father)
}
}
static
inline
void
close_files
(
struct
files_struct
*
files
)
{
int
i
,
j
;
j
=
0
;
for
(;;)
{
unsigned
long
set
=
files
->
open_fds
.
fds_bits
[
j
];
i
=
j
*
__NFDBITS
;
j
++
;
if
(
i
>=
NR_OPEN
)
break
;
while
(
set
)
{
if
(
set
&
1
)
close_fp
(
files
->
fd
[
i
]);
i
++
;
set
>>=
1
;
}
}
}
static
inline
void
__exit_files
(
struct
task_struct
*
tsk
)
{
struct
files_struct
*
files
=
tsk
->
files
;
...
...
@@ -400,14 +420,7 @@ static inline void __exit_files(struct task_struct *tsk)
if
(
files
)
{
tsk
->
files
=
NULL
;
if
(
!--
files
->
count
)
{
int
i
;
for
(
i
=
0
;
i
<
NR_OPEN
;
i
++
)
{
struct
file
*
filp
=
files
->
fd
[
i
];
if
(
!
filp
)
continue
;
files
->
fd
[
i
]
=
NULL
;
close_fp
(
filp
);
}
close_files
(
files
);
kfree
(
files
);
}
}
...
...
kernel/fork.c
View file @
b6a823e7
...
...
@@ -160,22 +160,33 @@ static inline int copy_fs(unsigned long clone_flags, struct task_struct * tsk)
static
inline
int
copy_files
(
unsigned
long
clone_flags
,
struct
task_struct
*
tsk
)
{
int
i
;
struct
files_struct
*
oldf
,
*
newf
;
struct
file
**
old_fds
,
**
new_fds
;
oldf
=
current
->
files
;
if
(
clone_flags
&
CLONE_FILES
)
{
current
->
files
->
count
++
;
oldf
->
count
++
;
return
0
;
}
tsk
->
files
=
kmalloc
(
sizeof
(
*
tsk
->
files
),
GFP_KERNEL
);
if
(
!
tsk
->
files
)
newf
=
kmalloc
(
sizeof
(
*
newf
),
GFP_KERNEL
);
tsk
->
files
=
newf
;
if
(
!
newf
)
return
-
1
;
tsk
->
files
->
count
=
1
;
memcpy
(
&
tsk
->
files
->
close_on_exec
,
&
current
->
files
->
close_on_exec
,
sizeof
(
tsk
->
files
->
close_on_exec
));
for
(
i
=
0
;
i
<
NR_OPEN
;
i
++
)
{
struct
file
*
f
=
current
->
files
->
fd
[
i
];
newf
->
count
=
1
;
newf
->
close_on_exec
=
oldf
->
close_on_exec
;
newf
->
open_fds
=
oldf
->
open_fds
;
old_fds
=
oldf
->
fd
;
new_fds
=
newf
->
fd
;
for
(
i
=
NR_OPEN
;
i
!=
0
;
i
--
)
{
struct
file
*
f
=
*
old_fds
;
old_fds
++
;
*
new_fds
=
f
;
new_fds
++
;
if
(
f
)
f
->
f_count
++
;
tsk
->
files
->
fd
[
i
]
=
f
;
}
return
0
;
}
...
...
net/ipv4/af_inet.c
View file @
b6a823e7
...
...
@@ -926,7 +926,7 @@ static int inet_bind(struct socket *sock, struct sockaddr *uaddr,
* Reuse ?
*/
if
(
!
sk2
->
dead
)
if
(
!
sk2
->
reuse
||
sk2
->
state
==
TCP_LISTEN
)
{
sti
();
return
(
-
EADDRINUSE
);
...
...
net/ipv4/tcp.c
View file @
b6a823e7
...
...
@@ -202,6 +202,7 @@
* improvement.
* Stefan Magdalinski : adjusted tcp_readable() to fix FIONREAD
* Willy Konynenberg : Transparent proxying support.
* Theodore Ts'o : Do secure TCP sequence numbers.
*
* To Fix:
* Fast path the code. Two things here - fix the window calculation
...
...
@@ -427,6 +428,7 @@
#include <linux/config.h>
#include <linux/types.h>
#include <linux/fcntl.h>
#include <linux/random.h>
#include <net/icmp.h>
#include <net/tcp.h>
...
...
@@ -1886,6 +1888,36 @@ static struct sock *tcp_accept(struct sock *sk, int flags)
goto
out
;
}
/*
* Check that a TCP address is unique, don't allow multiple
* connects to/from the same address
*/
static
int
tcp_unique_address
(
u32
saddr
,
u16
snum
,
u32
daddr
,
u16
dnum
)
{
int
retval
=
1
;
struct
sock
*
sk
;
/* Make sure we are allowed to connect here. */
cli
();
for
(
sk
=
tcp_prot
.
sock_array
[
snum
&
(
SOCK_ARRAY_SIZE
-
1
)];
sk
!=
NULL
;
sk
=
sk
->
next
)
{
/* hash collision? */
if
(
sk
->
num
!=
snum
)
continue
;
if
(
sk
->
saddr
!=
saddr
)
continue
;
if
(
sk
->
daddr
!=
daddr
)
continue
;
if
(
sk
->
dummy_th
.
dest
!=
dnum
)
continue
;
retval
=
0
;
break
;
}
sti
();
return
retval
;
}
/*
* This will initiate an outgoing connection.
...
...
@@ -1921,7 +1953,7 @@ static int tcp_connect(struct sock *sk, struct sockaddr_in *usin, int addr_len)
* connect() to INADDR_ANY means loopback (BSD'ism).
*/
if
(
usin
->
sin_addr
.
s_addr
==
INADDR_ANY
)
if
(
usin
->
sin_addr
.
s_addr
==
INADDR_ANY
)
usin
->
sin_addr
.
s_addr
=
ip_my_addr
();
/*
...
...
@@ -1931,27 +1963,26 @@ static int tcp_connect(struct sock *sk, struct sockaddr_in *usin, int addr_len)
if
((
atype
=
ip_chk_addr
(
usin
->
sin_addr
.
s_addr
))
==
IS_BROADCAST
||
atype
==
IS_MULTICAST
)
return
-
ENETUNREACH
;
if
(
!
tcp_unique_address
(
sk
->
saddr
,
sk
->
num
,
usin
->
sin_addr
.
s_addr
,
usin
->
sin_port
))
return
-
EADDRNOTAVAIL
;
lock_sock
(
sk
);
sk
->
daddr
=
usin
->
sin_addr
.
s_addr
;
sk
->
write_seq
=
tcp_init_seq
();
sk
->
window_seq
=
sk
->
write_seq
;
sk
->
rcv_ack_seq
=
sk
->
write_seq
-
1
;
sk
->
rcv_ack_cnt
=
1
;
sk
->
err
=
0
;
sk
->
dummy_th
.
dest
=
usin
->
sin_port
;
release_sock
(
sk
);
buff
=
sock_wmalloc
(
sk
,
MAX_SYN_SIZE
,
0
,
GFP_KERNEL
);
if
(
buff
==
NULL
)
{
release_sock
(
sk
);
return
(
-
ENOMEM
);
}
lock_sock
(
sk
);
buff
->
sk
=
sk
;
buff
->
free
=
0
;
buff
->
localroute
=
sk
->
localroute
;
/*
* Put in the IP header and routing stuff.
*/
...
...
@@ -1968,6 +1999,15 @@ static int tcp_connect(struct sock *sk, struct sockaddr_in *usin, int addr_len)
sk
->
saddr
=
rt
->
rt_src
;
sk
->
rcv_saddr
=
sk
->
saddr
;
/*
* Set up our outgoing TCP sequence number
*/
sk
->
write_seq
=
secure_tcp_sequence_number
(
sk
->
saddr
,
sk
->
daddr
,
sk
->
dummy_th
.
source
,
usin
->
sin_port
);
sk
->
window_seq
=
sk
->
write_seq
;
sk
->
rcv_ack_seq
=
sk
->
write_seq
-
1
;
t1
=
(
struct
tcphdr
*
)
skb_put
(
buff
,
sizeof
(
struct
tcphdr
));
memcpy
(
t1
,(
void
*
)
&
(
sk
->
dummy_th
),
sizeof
(
*
t1
));
...
...
net/ipv4/tcp_input.c
View file @
b6a823e7
...
...
@@ -28,9 +28,12 @@
* Eric Schenk : Skip fast retransmit on small windows.
* Eric schenk : Fixes to retransmission code to
* : avoid extra retransmission.
* Theodore Ts'o : Do secure TCP sequence numbers.
*/
#include <linux/config.h>
#include <linux/types.h>
#include <linux/random.h>
#include <net/tcp.h>
/*
...
...
@@ -208,7 +211,17 @@ static void bad_tcp_sequence(struct sock *sk, struct tcphdr *th, u32 end_seq,
* from the far end, but sometimes it means the far end lost
* an ACK we sent, so we better send an ACK.
*/
tcp_send_ack
(
sk
);
/*
* BEWARE! Unconditional answering by ack to out-of-window ack
* can result in infinite exchange of empty acks.
* This check cures bug, found by Michiel Boland, but
* not another possible cases.
* If we are in TCP_TIME_WAIT, we have already received
* FIN, so that our peer need not window update. If our
* ACK were lost, peer would retransmit his FIN anyway. --ANK
*/
if
(
sk
->
state
!=
TCP_TIME_WAIT
||
ntohl
(
th
->
seq
)
!=
end_seq
)
tcp_send_ack
(
sk
);
}
/*
...
...
@@ -1722,6 +1735,7 @@ int tcp_rcv(struct sk_buff *skb, struct device *dev, struct options *opt,
struct
tcphdr
*
th
;
struct
sock
*
sk
;
int
syn_ok
=
0
;
__u32
seq
;
#ifdef CONFIG_IP_TRANSPARENT_PROXY
int
r
;
#endif
...
...
@@ -1859,10 +1873,12 @@ int tcp_rcv(struct sk_buff *skb, struct device *dev, struct options *opt,
}
/*
* Guess we need to make a new socket up
* Guess we need to make a new socket up
*/
tcp_conn_request
(
sk
,
skb
,
daddr
,
saddr
,
opt
,
dev
,
tcp_init_seq
());
seq
=
secure_tcp_sequence_number
(
saddr
,
daddr
,
skb
->
h
.
th
->
dest
,
skb
->
h
.
th
->
source
);
tcp_conn_request
(
sk
,
skb
,
daddr
,
saddr
,
opt
,
dev
,
seq
);
/*
* Now we have several options: In theory there is nothing else
...
...
net/socket.c
View file @
b6a823e7
...
...
@@ -172,36 +172,31 @@ int move_addr_to_user(void *kaddr, int klen, void *uaddr, int *ulen)
static
int
get_fd
(
struct
inode
*
inode
)
{
int
fd
;
struct
file
*
file
;
/*
* Find a file descriptor suitable for return to the user.
*/
f
ile
=
get_empty_filp
();
if
(
!
file
)
return
(
-
1
);
f
d
=
get_unused_fd
();
if
(
fd
>=
0
)
{
struct
file
*
file
=
get_empty_filp
(
);
for
(
fd
=
0
;
fd
<
NR_OPEN
;
++
fd
)
if
(
!
current
->
files
->
fd
[
fd
])
break
;
if
(
fd
==
NR_OPEN
)
{
file
->
f_count
=
0
;
return
(
-
1
);
}
if
(
!
file
)
{
put_unused_fd
(
fd
);
return
-
ENFILE
;
}
FD_CLR
(
fd
,
&
current
->
files
->
close_on_exec
);
current
->
files
->
fd
[
fd
]
=
file
;
file
->
f_op
=
&
socket_file_ops
;
file
->
f_mode
=
3
;
file
->
f_flags
=
O_RDWR
;
file
->
f_count
=
1
;
file
->
f_inode
=
inode
;
if
(
inode
)
inode
->
i_count
++
;
file
->
f_pos
=
0
;
return
(
fd
);
file
->
f_op
=
&
socket_file_ops
;
file
->
f_mode
=
3
;
file
->
f_flags
=
O_RDWR
;
file
->
f_count
=
1
;
file
->
f_inode
=
inode
;
if
(
inode
)
inode
->
i_count
++
;
file
->
f_pos
=
0
;
}
return
fd
;
}
...
...
net/unix/af_unix.c
View file @
b6a823e7
...
...
@@ -710,10 +710,9 @@ static int unix_fd_copy(struct sock *sk, struct cmsghdr *cmsg, struct file **fp)
int
num
=
cmsg
->
cmsg_len
-
sizeof
(
struct
cmsghdr
);
int
i
;
int
*
fdp
=
(
int
*
)
cmsg
->
cmsg_data
;
num
/=
4
;
/* Odd bytes are forgotten in BSD not errored */
if
(
num
>=
UNIX_MAX_FD
)
num
/=
sizeof
(
int
);
/* Odd bytes are forgotten in BSD not errored */
if
(
num
>=
UNIX_MAX_FD
)
return
-
EINVAL
;
/*
...
...
@@ -728,9 +727,9 @@ static int unix_fd_copy(struct sock *sk, struct cmsghdr *cmsg, struct file **fp)
#if 0
printk("testing fd %d\n", fd);
#endif
if
(
fd
<
0
||
fd
>=
NR_OPEN
)
if
(
fd
<
0
||
fd
>=
NR_OPEN
)
return
-
EBADF
;
if
(
current
->
files
->
fd
[
fd
]
==
NULL
)
if
(
current
->
files
->
fd
[
fd
]
==
NULL
)
return
-
EBADF
;
}
...
...
@@ -759,30 +758,6 @@ static void unix_fd_free(struct sock *sk, struct file **fp, int num)
}
}
/*
* Count the free descriptors available to a process.
* Interpretation issue: Is the limit the highest descriptor (buggy
* allowing passed fd's higher up to cause a limit to be exceeded) -
* but how the old code did it - or like this...
*/
static
int
unix_files_free
(
void
)
{
int
i
;
int
n
=
0
;
for
(
i
=
0
;
i
<
NR_OPEN
;
i
++
)
{
if
(
current
->
files
->
fd
[
i
])
n
++
;
}
i
=
NR_OPEN
;
if
(
i
>
current
->
rlim
[
RLIMIT_NOFILE
].
rlim_cur
)
i
=
current
->
rlim
[
RLIMIT_NOFILE
].
rlim_cur
;
if
(
n
>=
i
)
return
0
;
return
i
-
n
;
}
/*
* Perform the AF_UNIX file descriptor pass out functionality. This
...
...
@@ -795,50 +770,39 @@ static void unix_detach_fds(struct sk_buff *skb, struct cmsghdr *cmsg)
/* count of space in parent for fds */
int
cmnum
;
struct
file
**
fp
;
struct
file
**
ufp
;
int
*
cmfptr
=
NULL
;
/* =NULL To keep gcc happy */
/* number of fds actually passed */
int
*
cmfptr
;
int
fdnum
;
int
ffree
;
int
ufn
=
0
;
if
(
cmsg
==
NULL
)
cmnum
=
0
;
else
cmfptr
=
NULL
;
cmnum
=
0
;
if
(
cmsg
)
{
cmnum
=
cmsg
->
cmsg_len
-
sizeof
(
struct
cmsghdr
);
cmnum
/=
sizeof
(
int
);
cmfptr
=
(
int
*
)
&
cmsg
->
cmsg_data
;
cmnum
=
(
cmsg
->
cmsg_len
-
sizeof
(
struct
cmsghdr
))
/
sizeof
(
int
);
cmfptr
=
(
int
*
)
&
cmsg
->
cmsg_data
;
}
memcpy
(
&
fdnum
,
skb
->
h
.
filp
,
sizeof
(
int
));
fp
=
(
struct
file
**
)(
skb
->
h
.
filp
+
sizeof
(
int
));
if
(
cmnum
>
fdnum
)
cmnum
=
fdnum
;
ffree
=
unix_files_free
();
if
(
cmnum
>
ffree
)
cmnum
=
ffree
;
ufp
=&
current
->
files
->
fd
[
0
];
fdnum
=
*
(
int
*
)
skb
->
h
.
filp
;
fp
=
(
struct
file
**
)(
skb
->
h
.
filp
+
sizeof
(
long
));
if
(
cmnum
>
fdnum
)
cmnum
=
fdnum
;
/*
* Copy those that fit
*/
for
(
i
=
0
;
i
<
cmnum
;
i
++
)
for
(
i
=
0
;
i
<
cmnum
;
i
++
)
{
/*
* Insert the fd
*/
while
(
ufp
[
ufn
]
!=
NULL
)
ufn
++
;
ufp
[
ufn
]
=
fp
[
i
];
*
cmfptr
++=
ufn
;
FD_CLR
(
ufn
,
&
current
->
files
->
close_on_exec
);
int
new_fd
=
get_unused_fd
();
if
(
new_fd
<
0
)
break
;
current
->
files
->
fd
[
new_fd
]
=
fp
[
i
];
*
cmfptr
++
=
new_fd
;
unix_notinflight
(
fp
[
i
]);
}
/*
* Dump those that don't
*/
for
(
;
i
<
fdnum
;
i
++
)
for
(
;
i
<
fdnum
;
i
++
)
{
close_fp
(
fp
[
i
]);
unix_notinflight
(
fp
[
i
]);
...
...
@@ -861,12 +825,12 @@ static void unix_destruct_fds(struct sk_buff *skb)
static
void
unix_attach_fds
(
int
fpnum
,
struct
file
**
fp
,
struct
sk_buff
*
skb
)
{
skb
->
h
.
filp
=
kmalloc
(
sizeof
(
int
)
+
fpnum
*
sizeof
(
struct
file
*
),
skb
->
h
.
filp
=
kmalloc
(
sizeof
(
long
)
+
fpnum
*
sizeof
(
struct
file
*
),
GFP_KERNEL
);
/* number of descriptors starts block */
memcpy
(
skb
->
h
.
filp
,
&
fpnum
,
sizeof
(
int
))
;
*
(
int
*
)
skb
->
h
.
filp
=
fpnum
;
/* actual descriptors */
memcpy
(
skb
->
h
.
filp
+
sizeof
(
int
),
fp
,
fpnum
*
sizeof
(
struct
file
*
));
memcpy
(
skb
->
h
.
filp
+
sizeof
(
long
),
fp
,
fpnum
*
sizeof
(
struct
file
*
));
skb
->
destructor
=
unix_destruct_fds
;
}
...
...
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