Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Contribute to GitLab
Sign in / Register
Toggle navigation
M
Magisk
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Administrator
Magisk
Commits
ffe47300
Commit
ffe47300
authored
Aug 19, 2021
by
topjohnwu
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Update recv/send fd function
parent
6f9c3c4f
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
84 additions
and
97 deletions
+84
-97
socket.cpp
native/jni/core/socket.cpp
+79
-94
socket.hpp
native/jni/include/socket.hpp
+5
-3
No files found.
native/jni/core/socket.cpp
View file @
ffe47300
...
@@ -20,122 +20,107 @@ socklen_t setup_sockaddr(sockaddr_un *sun, const char *name) {
...
@@ -20,122 +20,107 @@ socklen_t setup_sockaddr(sockaddr_un *sun, const char *name) {
return
socket_len
(
sun
);
return
socket_len
(
sun
);
}
}
int
socket_accept
(
int
sockfd
,
int
timeout
)
{
void
get_client_cred
(
int
fd
,
ucred
*
cred
)
{
struct
pollfd
pfd
=
{
socklen_t
len
=
sizeof
(
*
cred
);
.
fd
=
sockfd
,
getsockopt
(
fd
,
SOL_SOCKET
,
SO_PEERCRED
,
cred
,
&
len
);
.
events
=
POLL_IN
};
return
xpoll
(
&
pfd
,
1
,
timeout
*
1000
)
<=
0
?
-
1
:
xaccept4
(
sockfd
,
nullptr
,
nullptr
,
SOCK_CLOEXEC
);
}
}
void
get_client_cred
(
int
fd
,
struct
ucred
*
cred
)
{
static
int
send_fds
(
int
sockfd
,
void
*
cmsgbuf
,
size_t
bufsz
,
const
int
*
fds
,
int
cnt
)
{
socklen_t
ucred_length
=
sizeof
(
*
cred
);
iovec
iov
=
{
getsockopt
(
fd
,
SOL_SOCKET
,
SO_PEERCRED
,
cred
,
&
ucred_length
);
.
iov_base
=
&
cnt
,
}
.
iov_len
=
sizeof
(
cnt
),
};
msghdr
msg
=
{
.
msg_iov
=
&
iov
,
.
msg_iovlen
=
1
,
};
/*
if
(
cnt
)
{
* Receive a file descriptor from a Unix socket.
msg
.
msg_control
=
cmsgbuf
;
* Contributed by @mkasick
msg
.
msg_controllen
=
bufsz
;
*
cmsghdr
*
cmsg
=
CMSG_FIRSTHDR
(
&
msg
);
* Returns the file descriptor on success, or -1 if a file
cmsg
->
cmsg_len
=
CMSG_LEN
(
sizeof
(
int
)
*
cnt
);
* descriptor was not actually included in the message
cmsg
->
cmsg_level
=
SOL_SOCKET
;
*
cmsg
->
cmsg_type
=
SCM_RIGHTS
;
* On error the function terminates by calling exit(-1)
*/
int
recv_fd
(
int
sockfd
)
{
// Need to receive data from the message, otherwise don't care about it.
char
iovbuf
;
struct
cmsghdr
*
cmsg
;
struct
iovec
iov
=
{
memcpy
(
CMSG_DATA
(
cmsg
),
fds
,
sizeof
(
int
)
*
cnt
);
.
iov_base
=
&
iovbuf
,
}
.
iov_len
=
1
,
};
return
xsendmsg
(
sockfd
,
&
msg
,
0
);
}
int
send_fds
(
int
sockfd
,
const
int
*
fds
,
int
cnt
)
{
if
(
cnt
==
0
)
{
return
send_fds
(
sockfd
,
nullptr
,
0
,
nullptr
,
0
);
}
vector
<
char
>
cmsgbuf
;
cmsgbuf
.
resize
(
CMSG_SPACE
(
sizeof
(
int
)
*
cnt
));
return
send_fds
(
sockfd
,
cmsgbuf
.
data
(),
cmsgbuf
.
size
(),
fds
,
cnt
);
}
int
send_fd
(
int
sockfd
,
int
fd
)
{
if
(
fd
<
0
)
{
return
send_fds
(
sockfd
,
nullptr
,
0
,
nullptr
,
0
);
}
char
cmsgbuf
[
CMSG_SPACE
(
sizeof
(
int
))];
char
cmsgbuf
[
CMSG_SPACE
(
sizeof
(
int
))];
return
send_fds
(
sockfd
,
cmsgbuf
,
sizeof
(
cmsgbuf
),
&
fd
,
1
);
}
struct
msghdr
msg
=
{
static
void
*
recv_fds
(
int
sockfd
,
char
*
cmsgbuf
,
size_t
bufsz
,
int
cnt
)
{
iovec
iov
=
{
.
iov_base
=
&
cnt
,
.
iov_len
=
sizeof
(
cnt
),
};
msghdr
msg
=
{
.
msg_iov
=
&
iov
,
.
msg_iov
=
&
iov
,
.
msg_iovlen
=
1
,
.
msg_iovlen
=
1
,
.
msg_control
=
cmsgbuf
,
.
msg_control
=
cmsgbuf
,
.
msg_controllen
=
sizeof
(
cmsgbuf
),
.
msg_controllen
=
bufsz
};
};
xrecvmsg
(
sockfd
,
&
msg
,
MSG_WAITALL
);
xrecvmsg
(
sockfd
,
&
msg
,
MSG_WAITALL
);
cmsghdr
*
cmsg
=
CMSG_FIRSTHDR
(
&
msg
);
// Was a control message actually sent?
switch
(
msg
.
msg_controllen
)
{
if
(
msg
.
msg_controllen
!=
bufsz
||
case
0
:
cmsg
==
nullptr
||
// No, so the file descriptor was closed and won't be used.
cmsg
->
cmsg_len
!=
CMSG_LEN
(
sizeof
(
int
)
*
cnt
)
||
return
-
1
;
cmsg
->
cmsg_level
!=
SOL_SOCKET
||
case
sizeof
(
cmsgbuf
):
cmsg
->
cmsg_type
!=
SCM_RIGHTS
)
{
// Yes, grab the file descriptor from it.
return
nullptr
;
break
;
default:
goto
error
;
}
}
cmsg
=
CMSG_FIRSTHDR
(
&
msg
);
return
CMSG_DATA
(
cmsg
);
}
if
(
cmsg
==
nullptr
||
vector
<
int
>
recv_fds
(
int
sockfd
)
{
cmsg
->
cmsg_len
!=
CMSG_LEN
(
sizeof
(
int
))
||
// Peek fd count to allocate proper buffer
cmsg
->
cmsg_level
!=
SOL_SOCKET
||
int
cnt
;
cmsg
->
cmsg_type
!=
SCM_RIGHTS
)
{
recv
(
sockfd
,
&
cnt
,
sizeof
(
cnt
),
MSG_PEEK
);
error:
LOGE
(
"unable to read fd
\n
"
);
exit
(
-
1
);
}
return
*
(
int
*
)
CMSG_DATA
(
cmsg
);
vector
<
char
>
cmsgbuf
;
}
cmsgbuf
.
resize
(
CMSG_SPACE
(
sizeof
(
int
)
*
cnt
));
/*
* Send a file descriptor through a Unix socket.
* Contributed by @mkasick
*
* On error the function terminates by calling exit(-1)
*
* fd may be -1, in which case the dummy data is sent,
* but no control message with the FD is sent.
*/
void
send_fd
(
int
sockfd
,
int
fd
)
{
// Need to send some data in the message, this will do.
char
junk
[]
=
{
'\0'
};
struct
iovec
iov
=
{
.
iov_base
=
junk
,
.
iov_len
=
1
,
};
struct
msghdr
msg
=
{
vector
<
int
>
results
;
.
msg_iov
=
&
iov
,
void
*
data
=
recv_fds
(
sockfd
,
cmsgbuf
.
data
(),
cmsgbuf
.
size
(),
cnt
);
.
msg_iovlen
=
1
,
if
(
data
==
nullptr
)
};
return
results
;
results
.
resize
(
cnt
);
memcpy
(
results
.
data
(),
data
,
sizeof
(
int
)
*
cnt
);
return
results
;
}
int
recv_fd
(
int
sockfd
)
{
char
cmsgbuf
[
CMSG_SPACE
(
sizeof
(
int
))];
char
cmsgbuf
[
CMSG_SPACE
(
sizeof
(
int
))];
if
(
fd
!=
-
1
)
{
void
*
data
=
recv_fds
(
sockfd
,
cmsgbuf
,
sizeof
(
cmsgbuf
),
1
);
// Is the file descriptor actually open?
if
(
data
==
nullptr
)
if
(
fcntl
(
fd
,
F_GETFD
)
==
-
1
)
{
return
-
1
;
if
(
errno
!=
EBADF
)
{
PLOGE
(
"unable to send fd"
);
}
// It's closed, don't send a control message or sendmsg will EBADF.
}
else
{
// It's open, send the file descriptor in a control message.
msg
.
msg_control
=
cmsgbuf
;
msg
.
msg_controllen
=
sizeof
(
cmsgbuf
);
struct
cmsghdr
*
cmsg
=
CMSG_FIRSTHDR
(
&
msg
);
cmsg
->
cmsg_len
=
CMSG_LEN
(
sizeof
(
int
));
cmsg
->
cmsg_level
=
SOL_SOCKET
;
cmsg
->
cmsg_type
=
SCM_RIGHTS
;
*
(
int
*
)
CMSG_DATA
(
cmsg
)
=
fd
;
}
}
xsendmsg
(
sockfd
,
&
msg
,
0
);
int
result
;
memcpy
(
&
result
,
data
,
sizeof
(
int
));
return
result
;
}
}
int
read_int
(
int
fd
)
{
int
read_int
(
int
fd
)
{
...
...
native/jni/include/socket.hpp
View file @
ffe47300
...
@@ -3,12 +3,14 @@
...
@@ -3,12 +3,14 @@
#include <sys/un.h>
#include <sys/un.h>
#include <sys/socket.h>
#include <sys/socket.h>
#include <string_view>
#include <string_view>
#include <vector>
socklen_t
setup_sockaddr
(
sockaddr_un
*
sun
,
const
char
*
name
);
socklen_t
setup_sockaddr
(
sockaddr_un
*
sun
,
const
char
*
name
);
int
socket_accept
(
int
sockfd
,
int
timeout
);
void
get_client_cred
(
int
fd
,
ucred
*
cred
);
void
get_client_cred
(
int
fd
,
struct
ucred
*
cre
d
);
std
::
vector
<
int
>
recv_fds
(
int
sockf
d
);
int
recv_fd
(
int
sockfd
);
int
recv_fd
(
int
sockfd
);
void
send_fd
(
int
sockfd
,
int
fd
);
int
send_fds
(
int
sockfd
,
const
int
*
fds
,
int
cnt
);
int
send_fd
(
int
sockfd
,
int
fd
);
int
read_int
(
int
fd
);
int
read_int
(
int
fd
);
int
read_int_be
(
int
fd
);
int
read_int_be
(
int
fd
);
void
write_int
(
int
fd
,
int
val
);
void
write_int
(
int
fd
,
int
val
);
...
...
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