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
nexedi
linux
Commits
553f770e
Commit
553f770e
authored
Jul 08, 2017
by
Al Viro
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
ipc: move compat shmctl to native
Signed-off-by:
Al Viro
<
viro@zeniv.linux.org.uk
>
parent
9ba720c1
Changes
3
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
231 additions
and
235 deletions
+231
-235
ipc/compat.c
ipc/compat.c
+3
-230
ipc/shm.c
ipc/shm.c
+204
-5
ipc/util.h
ipc/util.h
+24
-0
No files found.
ipc/compat.c
View file @
553f770e
...
@@ -39,16 +39,6 @@ struct compat_msgbuf {
...
@@ -39,16 +39,6 @@ struct compat_msgbuf {
char
mtext
[
1
];
char
mtext
[
1
];
};
};
struct
compat_ipc_perm
{
key_t
key
;
__compat_uid_t
uid
;
__compat_gid_t
gid
;
__compat_uid_t
cuid
;
__compat_gid_t
cgid
;
compat_mode_t
mode
;
unsigned
short
seq
;
};
struct
compat_semid_ds
{
struct
compat_semid_ds
{
struct
compat_ipc_perm
sem_perm
;
struct
compat_ipc_perm
sem_perm
;
compat_time_t
sem_otime
;
compat_time_t
sem_otime
;
...
@@ -76,44 +66,12 @@ struct compat_msqid_ds {
...
@@ -76,44 +66,12 @@ struct compat_msqid_ds {
compat_ipc_pid_t
msg_lrpid
;
compat_ipc_pid_t
msg_lrpid
;
};
};
struct
compat_shmid_ds
{
struct
compat_ipc_perm
shm_perm
;
int
shm_segsz
;
compat_time_t
shm_atime
;
compat_time_t
shm_dtime
;
compat_time_t
shm_ctime
;
compat_ipc_pid_t
shm_cpid
;
compat_ipc_pid_t
shm_lpid
;
unsigned
short
shm_nattch
;
unsigned
short
shm_unused
;
compat_uptr_t
shm_unused2
;
compat_uptr_t
shm_unused3
;
};
struct
compat_ipc_kludge
{
struct
compat_ipc_kludge
{
compat_uptr_t
msgp
;
compat_uptr_t
msgp
;
compat_long_t
msgtyp
;
compat_long_t
msgtyp
;
};
};
struct
compat_shminfo64
{
static
inline
int
__compat_ipc_parse_version
(
int
*
cmd
)
compat_ulong_t
shmmax
;
compat_ulong_t
shmmin
;
compat_ulong_t
shmmni
;
compat_ulong_t
shmseg
;
compat_ulong_t
shmall
;
compat_ulong_t
__unused1
;
compat_ulong_t
__unused2
;
compat_ulong_t
__unused3
;
compat_ulong_t
__unused4
;
};
struct
compat_shm_info
{
compat_int_t
used_ids
;
compat_ulong_t
shm_tot
,
shm_rss
,
shm_swp
;
compat_ulong_t
swap_attempts
,
swap_successes
;
};
static
inline
int
compat_ipc_parse_version
(
int
*
cmd
)
{
{
#ifdef CONFIG_ARCH_WANT_COMPAT_IPC_PARSE_VERSION
#ifdef CONFIG_ARCH_WANT_COMPAT_IPC_PARSE_VERSION
int
version
=
*
cmd
&
IPC_64
;
int
version
=
*
cmd
&
IPC_64
;
...
@@ -241,7 +199,7 @@ static long do_compat_semctl(int first, int second, int third, u32 pad)
...
@@ -241,7 +199,7 @@ static long do_compat_semctl(int first, int second, int third, u32 pad)
int
err
,
err2
;
int
err
,
err2
;
struct
semid64_ds
sem64
;
struct
semid64_ds
sem64
;
struct
semid64_ds
__user
*
up64
;
struct
semid64_ds
__user
*
up64
;
int
version
=
compat_ipc_parse_version
(
&
third
);
int
version
=
__
compat_ipc_parse_version
(
&
third
);
memset
(
&
sem64
,
0
,
sizeof
(
sem64
));
memset
(
&
sem64
,
0
,
sizeof
(
sem64
));
...
@@ -499,7 +457,7 @@ COMPAT_SYSCALL_DEFINE3(msgctl, int, first, int, second, void __user *, uptr)
...
@@ -499,7 +457,7 @@ COMPAT_SYSCALL_DEFINE3(msgctl, int, first, int, second, void __user *, uptr)
{
{
int
err
,
err2
;
int
err
,
err2
;
struct
msqid64_ds
m64
;
struct
msqid64_ds
m64
;
int
version
=
compat_ipc_parse_version
(
&
second
);
int
version
=
__
compat_ipc_parse_version
(
&
second
);
void
__user
*
p
;
void
__user
*
p
;
memset
(
&
m64
,
0
,
sizeof
(
m64
));
memset
(
&
m64
,
0
,
sizeof
(
m64
));
...
@@ -561,191 +519,6 @@ COMPAT_SYSCALL_DEFINE3(shmat, int, shmid, compat_uptr_t, shmaddr, int, shmflg)
...
@@ -561,191 +519,6 @@ COMPAT_SYSCALL_DEFINE3(shmat, int, shmid, compat_uptr_t, shmaddr, int, shmflg)
return
(
long
)
ret
;
return
(
long
)
ret
;
}
}
static
inline
int
get_compat_shmid64_ds
(
struct
shmid64_ds
*
sem64
,
struct
compat_shmid64_ds
__user
*
up64
)
{
if
(
!
access_ok
(
VERIFY_READ
,
up64
,
sizeof
(
*
up64
)))
return
-
EFAULT
;
return
__get_compat_ipc64_perm
(
&
sem64
->
shm_perm
,
&
up64
->
shm_perm
);
}
static
inline
int
get_compat_shmid_ds
(
struct
shmid64_ds
*
s
,
struct
compat_shmid_ds
__user
*
up
)
{
if
(
!
access_ok
(
VERIFY_READ
,
up
,
sizeof
(
*
up
)))
return
-
EFAULT
;
return
__get_compat_ipc_perm
(
&
s
->
shm_perm
,
&
up
->
shm_perm
);
}
static
inline
int
put_compat_shmid64_ds
(
struct
shmid64_ds
*
sem64
,
struct
compat_shmid64_ds
__user
*
up64
)
{
int
err
;
if
(
!
access_ok
(
VERIFY_WRITE
,
up64
,
sizeof
(
*
up64
)))
return
-
EFAULT
;
err
=
__put_compat_ipc64_perm
(
&
sem64
->
shm_perm
,
&
up64
->
shm_perm
);
err
|=
__put_user
(
sem64
->
shm_atime
,
&
up64
->
shm_atime
);
err
|=
__put_user
(
sem64
->
shm_dtime
,
&
up64
->
shm_dtime
);
err
|=
__put_user
(
sem64
->
shm_ctime
,
&
up64
->
shm_ctime
);
err
|=
__put_user
(
sem64
->
shm_segsz
,
&
up64
->
shm_segsz
);
err
|=
__put_user
(
sem64
->
shm_nattch
,
&
up64
->
shm_nattch
);
err
|=
__put_user
(
sem64
->
shm_cpid
,
&
up64
->
shm_cpid
);
err
|=
__put_user
(
sem64
->
shm_lpid
,
&
up64
->
shm_lpid
);
return
err
;
}
static
inline
int
put_compat_shmid_ds
(
struct
shmid64_ds
*
s
,
struct
compat_shmid_ds
__user
*
up
)
{
int
err
;
if
(
!
access_ok
(
VERIFY_WRITE
,
up
,
sizeof
(
*
up
)))
return
-
EFAULT
;
err
=
__put_compat_ipc_perm
(
&
s
->
shm_perm
,
&
up
->
shm_perm
);
err
|=
__put_user
(
s
->
shm_atime
,
&
up
->
shm_atime
);
err
|=
__put_user
(
s
->
shm_dtime
,
&
up
->
shm_dtime
);
err
|=
__put_user
(
s
->
shm_ctime
,
&
up
->
shm_ctime
);
err
|=
__put_user
(
s
->
shm_segsz
,
&
up
->
shm_segsz
);
err
|=
__put_user
(
s
->
shm_nattch
,
&
up
->
shm_nattch
);
err
|=
__put_user
(
s
->
shm_cpid
,
&
up
->
shm_cpid
);
err
|=
__put_user
(
s
->
shm_lpid
,
&
up
->
shm_lpid
);
return
err
;
}
static
inline
int
put_compat_shminfo64
(
struct
shminfo64
*
smi
,
struct
compat_shminfo64
__user
*
up64
)
{
int
err
;
if
(
!
access_ok
(
VERIFY_WRITE
,
up64
,
sizeof
(
*
up64
)))
return
-
EFAULT
;
if
(
smi
->
shmmax
>
INT_MAX
)
smi
->
shmmax
=
INT_MAX
;
err
=
__put_user
(
smi
->
shmmax
,
&
up64
->
shmmax
);
err
|=
__put_user
(
smi
->
shmmin
,
&
up64
->
shmmin
);
err
|=
__put_user
(
smi
->
shmmni
,
&
up64
->
shmmni
);
err
|=
__put_user
(
smi
->
shmseg
,
&
up64
->
shmseg
);
err
|=
__put_user
(
smi
->
shmall
,
&
up64
->
shmall
);
return
err
;
}
static
inline
int
put_compat_shminfo
(
struct
shminfo64
*
smi
,
struct
shminfo
__user
*
up
)
{
int
err
;
if
(
!
access_ok
(
VERIFY_WRITE
,
up
,
sizeof
(
*
up
)))
return
-
EFAULT
;
if
(
smi
->
shmmax
>
INT_MAX
)
smi
->
shmmax
=
INT_MAX
;
err
=
__put_user
(
smi
->
shmmax
,
&
up
->
shmmax
);
err
|=
__put_user
(
smi
->
shmmin
,
&
up
->
shmmin
);
err
|=
__put_user
(
smi
->
shmmni
,
&
up
->
shmmni
);
err
|=
__put_user
(
smi
->
shmseg
,
&
up
->
shmseg
);
err
|=
__put_user
(
smi
->
shmall
,
&
up
->
shmall
);
return
err
;
}
static
inline
int
put_compat_shm_info
(
struct
shm_info
__user
*
ip
,
struct
compat_shm_info
__user
*
uip
)
{
int
err
;
struct
shm_info
si
;
if
(
!
access_ok
(
VERIFY_WRITE
,
uip
,
sizeof
(
*
uip
))
||
copy_from_user
(
&
si
,
ip
,
sizeof
(
si
)))
return
-
EFAULT
;
err
=
__put_user
(
si
.
used_ids
,
&
uip
->
used_ids
);
err
|=
__put_user
(
si
.
shm_tot
,
&
uip
->
shm_tot
);
err
|=
__put_user
(
si
.
shm_rss
,
&
uip
->
shm_rss
);
err
|=
__put_user
(
si
.
shm_swp
,
&
uip
->
shm_swp
);
err
|=
__put_user
(
si
.
swap_attempts
,
&
uip
->
swap_attempts
);
err
|=
__put_user
(
si
.
swap_successes
,
&
uip
->
swap_successes
);
return
err
;
}
COMPAT_SYSCALL_DEFINE3
(
shmctl
,
int
,
first
,
int
,
second
,
void
__user
*
,
uptr
)
{
void
__user
*
p
;
struct
shmid64_ds
sem64
;
struct
shminfo64
smi
;
int
err
,
err2
;
int
version
=
compat_ipc_parse_version
(
&
second
);
memset
(
&
sem64
,
0
,
sizeof
(
sem64
));
switch
(
second
&
(
~
IPC_64
))
{
case
IPC_RMID
:
case
SHM_LOCK
:
case
SHM_UNLOCK
:
err
=
sys_shmctl
(
first
,
second
,
uptr
);
break
;
case
IPC_INFO
:
p
=
compat_alloc_user_space
(
sizeof
(
smi
));
err
=
sys_shmctl
(
first
,
second
,
p
);
if
(
err
<
0
)
break
;
if
(
copy_from_user
(
&
smi
,
p
,
sizeof
(
smi
)))
err2
=
-
EFAULT
;
else
if
(
version
==
IPC_64
)
err2
=
put_compat_shminfo64
(
&
smi
,
uptr
);
else
err2
=
put_compat_shminfo
(
&
smi
,
uptr
);
if
(
err2
)
err
=
-
EFAULT
;
break
;
case
IPC_SET
:
if
(
version
==
IPC_64
)
err
=
get_compat_shmid64_ds
(
&
sem64
,
uptr
);
else
err
=
get_compat_shmid_ds
(
&
sem64
,
uptr
);
if
(
err
)
break
;
p
=
compat_alloc_user_space
(
sizeof
(
sem64
));
if
(
copy_to_user
(
p
,
&
sem64
,
sizeof
(
sem64
)))
err
=
-
EFAULT
;
else
err
=
sys_shmctl
(
first
,
second
,
p
);
break
;
case
IPC_STAT
:
case
SHM_STAT
:
p
=
compat_alloc_user_space
(
sizeof
(
sem64
));
err
=
sys_shmctl
(
first
,
second
,
p
);
if
(
err
<
0
)
break
;
if
(
copy_from_user
(
&
sem64
,
p
,
sizeof
(
sem64
)))
err2
=
-
EFAULT
;
else
if
(
version
==
IPC_64
)
err2
=
put_compat_shmid64_ds
(
&
sem64
,
uptr
);
else
err2
=
put_compat_shmid_ds
(
&
sem64
,
uptr
);
if
(
err2
)
err
=
-
EFAULT
;
break
;
case
SHM_INFO
:
p
=
compat_alloc_user_space
(
sizeof
(
struct
shm_info
));
err
=
sys_shmctl
(
first
,
second
,
p
);
if
(
err
<
0
)
break
;
err2
=
put_compat_shm_info
(
p
,
uptr
);
if
(
err2
)
err
=
-
EFAULT
;
break
;
default:
err
=
-
EINVAL
;
break
;
}
return
err
;
}
COMPAT_SYSCALL_DEFINE4
(
semtimedop
,
int
,
semid
,
struct
sembuf
__user
*
,
tsems
,
COMPAT_SYSCALL_DEFINE4
(
semtimedop
,
int
,
semid
,
struct
sembuf
__user
*
,
tsems
,
unsigned
,
nsops
,
unsigned
,
nsops
,
const
struct
compat_timespec
__user
*
,
timeout
)
const
struct
compat_timespec
__user
*
,
timeout
)
...
...
ipc/shm.c
View file @
553f770e
...
@@ -1030,7 +1030,7 @@ SYSCALL_DEFINE3(shmctl, int, shmid, int, cmd, struct shmid_ds __user *, buf)
...
@@ -1030,7 +1030,7 @@ SYSCALL_DEFINE3(shmctl, int, shmid, int, cmd, struct shmid_ds __user *, buf)
{
{
int
err
,
version
;
int
err
,
version
;
struct
ipc_namespace
*
ns
;
struct
ipc_namespace
*
ns
;
struct
shmid64_ds
tbuf
;
struct
shmid64_ds
sem64
;
if
(
cmd
<
0
||
shmid
<
0
)
if
(
cmd
<
0
||
shmid
<
0
)
return
-
EINVAL
;
return
-
EINVAL
;
...
@@ -1059,18 +1059,19 @@ SYSCALL_DEFINE3(shmctl, int, shmid, int, cmd, struct shmid_ds __user *, buf)
...
@@ -1059,18 +1059,19 @@ SYSCALL_DEFINE3(shmctl, int, shmid, int, cmd, struct shmid_ds __user *, buf)
}
}
case
SHM_STAT
:
case
SHM_STAT
:
case
IPC_STAT
:
{
case
IPC_STAT
:
{
err
=
shmctl_stat
(
ns
,
shmid
,
cmd
,
&
tbuf
);
err
=
shmctl_stat
(
ns
,
shmid
,
cmd
,
&
sem64
);
if
(
err
<
0
)
if
(
err
<
0
)
return
err
;
return
err
;
if
(
copy_shmid_to_user
(
buf
,
&
tbuf
,
version
))
if
(
copy_shmid_to_user
(
buf
,
&
sem64
,
version
))
err
=
-
EFAULT
;
err
=
-
EFAULT
;
return
err
;
return
err
;
}
}
case
IPC_SET
:
case
IPC_SET
:
if
(
copy_shmid_from_user
(
&
tbuf
,
buf
,
version
))
if
(
copy_shmid_from_user
(
&
sem64
,
buf
,
version
))
return
-
EFAULT
;
return
-
EFAULT
;
/* fallthru */
case
IPC_RMID
:
case
IPC_RMID
:
return
shmctl_down
(
ns
,
shmid
,
cmd
,
&
tbuf
);
return
shmctl_down
(
ns
,
shmid
,
cmd
,
&
sem64
);
case
SHM_LOCK
:
case
SHM_LOCK
:
case
SHM_UNLOCK
:
case
SHM_UNLOCK
:
return
shmctl_do_lock
(
ns
,
shmid
,
cmd
);
return
shmctl_do_lock
(
ns
,
shmid
,
cmd
);
...
@@ -1079,6 +1080,204 @@ SYSCALL_DEFINE3(shmctl, int, shmid, int, cmd, struct shmid_ds __user *, buf)
...
@@ -1079,6 +1080,204 @@ SYSCALL_DEFINE3(shmctl, int, shmid, int, cmd, struct shmid_ds __user *, buf)
}
}
}
}
#ifdef CONFIG_COMPAT
struct
compat_shmid_ds
{
struct
compat_ipc_perm
shm_perm
;
int
shm_segsz
;
compat_time_t
shm_atime
;
compat_time_t
shm_dtime
;
compat_time_t
shm_ctime
;
compat_ipc_pid_t
shm_cpid
;
compat_ipc_pid_t
shm_lpid
;
unsigned
short
shm_nattch
;
unsigned
short
shm_unused
;
compat_uptr_t
shm_unused2
;
compat_uptr_t
shm_unused3
;
};
struct
compat_shminfo64
{
compat_ulong_t
shmmax
;
compat_ulong_t
shmmin
;
compat_ulong_t
shmmni
;
compat_ulong_t
shmseg
;
compat_ulong_t
shmall
;
compat_ulong_t
__unused1
;
compat_ulong_t
__unused2
;
compat_ulong_t
__unused3
;
compat_ulong_t
__unused4
;
};
struct
compat_shm_info
{
compat_int_t
used_ids
;
compat_ulong_t
shm_tot
,
shm_rss
,
shm_swp
;
compat_ulong_t
swap_attempts
,
swap_successes
;
};
static
int
copy_compat_shminfo_to_user
(
void
__user
*
buf
,
struct
shminfo64
*
in
,
int
version
)
{
if
(
in
->
shmmax
>
INT_MAX
)
in
->
shmmax
=
INT_MAX
;
if
(
version
==
IPC_64
)
{
struct
compat_shminfo64
info
;
memset
(
&
info
,
0
,
sizeof
(
info
));
info
.
shmmax
=
in
->
shmmax
;
info
.
shmmin
=
in
->
shmmin
;
info
.
shmmni
=
in
->
shmmni
;
info
.
shmseg
=
in
->
shmseg
;
info
.
shmall
=
in
->
shmall
;
return
copy_to_user
(
buf
,
&
info
,
sizeof
(
info
));
}
else
{
struct
shminfo
info
;
memset
(
&
info
,
0
,
sizeof
(
info
));
info
.
shmmax
=
in
->
shmmax
;
info
.
shmmin
=
in
->
shmmin
;
info
.
shmmni
=
in
->
shmmni
;
info
.
shmseg
=
in
->
shmseg
;
info
.
shmall
=
in
->
shmall
;
return
copy_to_user
(
buf
,
&
info
,
sizeof
(
info
));
}
}
static
int
put_compat_shm_info
(
struct
shm_info
*
ip
,
struct
compat_shm_info
__user
*
uip
)
{
struct
compat_shm_info
info
;
memset
(
&
info
,
0
,
sizeof
(
info
));
info
.
used_ids
=
ip
->
used_ids
;
info
.
shm_tot
=
ip
->
shm_tot
;
info
.
shm_rss
=
ip
->
shm_rss
;
info
.
shm_swp
=
ip
->
shm_swp
;
info
.
swap_attempts
=
ip
->
swap_attempts
;
info
.
swap_successes
=
ip
->
swap_successes
;
return
copy_to_user
(
up
,
&
info
,
sizeof
(
info
));
}
static
int
copy_compat_shmid_to_user
(
void
__user
*
buf
,
struct
shmid64_ds
*
in
,
int
version
)
{
if
(
version
==
IPC_64
)
{
struct
compat_shmid64_ds
v
;
memset
(
&
v
,
0
,
sizeof
(
v
));
v
.
shm_perm
.
key
=
in
->
shm_perm
.
key
;
v
.
shm_perm
.
uid
=
in
->
shm_perm
.
uid
;
v
.
shm_perm
.
gid
=
in
->
shm_perm
.
gid
;
v
.
shm_perm
.
cuid
=
in
->
shm_perm
.
cuid
;
v
.
shm_perm
.
cgid
=
in
->
shm_perm
.
cgid
;
v
.
shm_perm
.
mode
=
in
->
shm_perm
.
mode
;
v
.
shm_perm
.
seq
=
in
->
shm_perm
.
seq
;
v
.
shm_atime
=
in
->
shm_atime
;
v
.
shm_dtime
=
in
->
shm_dtime
;
v
.
shm_ctime
=
in
->
shm_ctime
;
v
.
shm_segsz
=
in
->
shm_segsz
;
v
.
shm_nattch
=
in
->
shm_nattch
;
v
.
shm_cpid
=
in
->
shm_cpid
;
v
.
shm_lpid
=
in
->
shm_lpid
;
return
copy_to_user
(
buf
,
&
v
,
sizeof
(
v
));
}
else
{
struct
compat_shmid_ds
v
;
memset
(
&
v
,
0
,
sizeof
(
v
));
v
.
shm_perm
.
key
=
in
->
shm_perm
.
key
;
SET_UID
(
v
.
shm_perm
.
uid
,
in
->
shm_perm
.
uid
);
SET_GID
(
v
.
shm_perm
.
gid
,
in
->
shm_perm
.
gid
);
SET_UID
(
v
.
shm_perm
.
cuid
,
in
->
shm_perm
.
cuid
);
SET_GID
(
v
.
shm_perm
.
cgid
,
in
->
shm_perm
.
cgid
);
v
.
shm_perm
.
mode
=
in
->
shm_perm
.
mode
;
v
.
shm_perm
.
seq
=
in
->
shm_perm
.
seq
;
v
.
shm_atime
=
in
->
shm_atime
;
v
.
shm_dtime
=
in
->
shm_dtime
;
v
.
shm_ctime
=
in
->
shm_ctime
;
v
.
shm_segsz
=
in
->
shm_segsz
;
v
.
shm_nattch
=
in
->
shm_nattch
;
v
.
shm_cpid
=
in
->
shm_cpid
;
v
.
shm_lpid
=
in
->
shm_lpid
;
return
copy_to_user
(
buf
,
&
v
,
sizeof
(
v
));
}
}
static
int
copy_compat_shmid_from_user
(
struct
shmid64_ds
*
out
,
void
__user
*
buf
,
int
version
)
{
memset
(
out
,
0
,
sizeof
(
*
out
));
if
(
version
==
IPC_64
)
{
struct
compat_shmid64_ds
*
p
=
buf
;
struct
compat_ipc64_perm
v
;
if
(
copy_from_user
(
&
v
,
&
p
->
shm_perm
,
sizeof
(
v
)))
return
-
EFAULT
;
out
->
shm_perm
.
uid
=
v
.
uid
;
out
->
shm_perm
.
gid
=
v
.
gid
;
out
->
shm_perm
.
mode
=
v
.
mode
;
}
else
{
struct
compat_shmid_ds
*
p
=
buf
;
struct
compat_ipc_perm
v
;
if
(
copy_from_user
(
&
v
,
&
p
->
shm_perm
,
sizeof
(
v
)))
return
-
EFAULT
;
out
->
shm_perm
.
uid
=
v
.
uid
;
out
->
shm_perm
.
gid
=
v
.
gid
;
out
->
shm_perm
.
mode
=
v
.
mode
;
}
return
0
;
}
COMPAT_SYSCALL_DEFINE3
(
shmctl
,
int
,
shmid
,
int
,
cmd
,
void
__user
*
,
uptr
)
{
struct
ipc_namespace
*
ns
;
struct
shmid64_ds
sem64
;
int
version
=
compat_ipc_parse_version
(
&
cmd
);
int
err
;
ns
=
current
->
nsproxy
->
ipc_ns
;
if
(
cmd
<
0
||
shmid
<
0
)
return
-
EINVAL
;
switch
(
cmd
)
{
case
IPC_INFO
:
{
struct
shminfo64
shminfo
;
err
=
shmctl_ipc_info
(
ns
,
&
shminfo
);
if
(
err
<
0
)
return
err
;
if
(
copy_compat_shminfo_to_user
(
uptr
,
&
shminfo
,
version
))
err
=
-
EFAULT
;
return
err
;
}
case
SHM_INFO
:
{
struct
shm_info
shm_info
;
err
=
shmctl_shm_info
(
ns
,
&
shm_info
);
if
(
err
<
0
)
return
err
;
if
(
put_compat_shm_info
(
&
shm_info
,
uptr
))
err
=
-
EFAULT
;
return
err
;
}
case
IPC_STAT
:
case
SHM_STAT
:
err
=
shmctl_stat
(
ns
,
shmid
,
cmd
,
&
sem64
);
if
(
err
<
0
)
return
err
;
if
(
copy_compat_shmid_to_user
(
&
sem64
,
uptr
,
version
))
err
=
-
EFAULT
;
return
err
;
case
IPC_SET
:
if
(
copy_compat_shmid_from_user
(
&
sem64
,
uptr
,
version
))
return
-
EFAULT
;
/* fallthru */
case
IPC_RMID
:
return
shmctl_down
(
ns
,
shmid
,
cmd
,
&
sem64
);
case
SHM_LOCK
:
case
SHM_UNLOCK
:
return
shmctl_do_lock
(
ns
,
shmid
,
cmd
);
break
;
default:
return
-
EINVAL
;
}
return
err
;
}
#endif
/*
/*
* Fix shmaddr, allocate descriptor, map shm, add attach descriptor to lists.
* Fix shmaddr, allocate descriptor, map shm, add attach descriptor to lists.
*
*
...
...
ipc/util.h
View file @
553f770e
...
@@ -191,4 +191,28 @@ int ipcget(struct ipc_namespace *ns, struct ipc_ids *ids,
...
@@ -191,4 +191,28 @@ int ipcget(struct ipc_namespace *ns, struct ipc_ids *ids,
const
struct
ipc_ops
*
ops
,
struct
ipc_params
*
params
);
const
struct
ipc_ops
*
ops
,
struct
ipc_params
*
params
);
void
free_ipcs
(
struct
ipc_namespace
*
ns
,
struct
ipc_ids
*
ids
,
void
free_ipcs
(
struct
ipc_namespace
*
ns
,
struct
ipc_ids
*
ids
,
void
(
*
free
)(
struct
ipc_namespace
*
,
struct
kern_ipc_perm
*
));
void
(
*
free
)(
struct
ipc_namespace
*
,
struct
kern_ipc_perm
*
));
#ifdef CONFIG_COMPAT
#include <linux/compat.h>
struct
compat_ipc_perm
{
key_t
key
;
__compat_uid_t
uid
;
__compat_gid_t
gid
;
__compat_uid_t
cuid
;
__compat_gid_t
cgid
;
compat_mode_t
mode
;
unsigned
short
seq
;
};
static
inline
int
compat_ipc_parse_version
(
int
*
cmd
)
{
#ifdef CONFIG_ARCH_WANT_COMPAT_IPC_PARSE_VERSION
int
version
=
*
cmd
&
IPC_64
;
*
cmd
&=
~
IPC_64
;
return
version
;
#else
return
IPC_64
;
#endif
}
#endif
#endif
#endif
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