Toggle navigation
Toggle navigation
This project
Loading...
Sign in
UT
/
clsync
Go to a project
Toggle navigation
Toggle navigation pinning
Projects
Groups
Snippets
Help
Project
Activity
Repository
Pipelines
Graphs
Issues
0
Merge Requests
0
Wiki
Network
Create a new issue
Builds
Commits
Authored by
redmine
2014-06-28 19:14:31 +0400
Browse Files
Options
Browse Files
Download
Email Patches
Plain Diff
Commit
d57a446deb72f7140df5c46ed60c655da367b29d
d57a446d
1 parent
ecc53140
Added support of read()/write() signalling (not enabled by default)
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
88 additions
and
5 deletions
configuration.h
privileged.c
syscalls.h
configuration.h
View file @
d57a446
...
...
@@ -155,3 +155,5 @@ filesz:1M\n\
#define DEFAULT_GID 65534
#define DEFAULT_CAPS_INHERIT CI_EMPTY
//#define READWRITE_SIGNALLING
...
...
privileged.c
View file @
d57a446
...
...
@@ -20,6 +20,7 @@
#include "common.h" // ctx.h
#include "ctx.h" // ctx_t
#include "error.h" // debug()
#include "syscalls.h" // read_inf()/write_inf()
#ifdef CAPABILITIES_SUPPORT
# include <pthread.h> // pthread_create()
...
...
@@ -50,6 +51,13 @@ pthread_cond_t pthread_cond_privileged = PTHREAD_COND_INITIALIZER;
pthread_cond_t
pthread_cond_action
=
PTHREAD_COND_INITIALIZER
;
pthread_cond_t
pthread_cond_runner
=
PTHREAD_COND_INITIALIZER
;
#ifdef READWRITE_SIGNALLING
int
priv_read_fd
;
int
priv_write_fd
;
int
nonp_read_fd
;
int
nonp_write_fd
;
#endif
enum
privileged_action
{
PA_UNKNOWN
=
0
,
...
...
@@ -326,6 +334,7 @@ int privileged_execvp_check_arguments(struct pa_options *opts, const char *u_fil
}
}
i
=
0
;
while
(
i
<
opts
->
permitted_hookfiles
)
{
if
(
!
strcmp
(
opts
->
permitted_hookfile
[
i
],
u_file
))
return
0
;
...
...
@@ -398,6 +407,9 @@ int pa_setup(struct pa_options *opts, ctx_t *ctx_p, uid_t *exec_uid_p, gid_t *ex
static
int
privileged_handler_running
=
1
;
void
*
privileged_handler
(
void
*
_ctx_p
)
{
#ifdef READWRITE_SIGNALLING
char
buf
[
1
]
=
{
0
};
#endif
int
setup
=
0
;
ctx_t
*
ctx_p
=
_ctx_p
;
uid_t
exec_uid
=
65535
;
...
...
@@ -421,10 +433,18 @@ void *privileged_handler(void *_ctx_p)
debug
(
2
,
"Running the loop"
);
while
(
privileged_handler_running
)
{
// Waiting for command
#ifdef _DEBUG_FORCE
debug
(
3
,
"Waiting for command"
,
cmd
.
action
);
#endif
#ifdef READWRITE_SIGNALLING
read_inf
(
priv_read_fd
,
buf
,
1
);
#else
pthread_cond_wait
(
&
pthread_cond_privileged
,
&
pthread_mutex_privileged
);
#endif
#ifdef _DEBUG_FORCE
debug
(
3
,
"Got command %u"
,
cmd
.
action
);
#endif
if
(
!
setup
&&
cmd
.
action
!=
PA_SETUP
)
critical
(
"A try to use commands before PA_SETUP"
);
...
...
@@ -501,10 +521,16 @@ void *privileged_handler(void *_ctx_p)
}
cmd
.
_errno
=
errno
;
#ifdef _DEBUG_FORCE
debug
(
3
,
"Result: %p, errno: %u. Sending the signal to non-privileged thread."
,
cmd
.
ret
,
cmd
.
_errno
);
#endif
#ifdef READWRITE_SIGNALLING
write_inf
(
nonp_write_fd
,
buf
,
1
);
#else
pthread_mutex_lock
(
&
pthread_mutex_action_signal
);
pthread_mutex_unlock
(
&
pthread_mutex_action_signal
);
pthread_cond_signal
(
&
pthread_cond_action
);
#endif
}
pthread_mutex_unlock
(
&
pthread_mutex_privileged
);
...
...
@@ -512,39 +538,62 @@ void *privileged_handler(void *_ctx_p)
return
0
;
}
int
privileged_action
(
static
inline
int
privileged_action
(
enum
privileged_action
action
,
void
*
arg
,
void
**
ret_p
)
{
#ifdef READWRITE_SIGNALLING
char
buf
[
1
]
=
{
0
};
#endif
#ifdef _DEBUG_FORCE
debug
(
3
,
"(%u, %p, %p)"
,
action
,
arg
,
ret_p
);
#endif
pthread_mutex_lock
(
&
pthread_mutex_action_entrance
);
#ifndef READWRITE_SIGNALLING
pthread_mutex_lock
(
&
pthread_mutex_action_signal
);
debug
(
4
,
"Waiting the privileged thread to get prepared for signal"
);
pthread_mutex_lock
(
&
pthread_mutex_privileged
);
pthread_mutex_unlock
(
&
pthread_mutex_privileged
);
#endif
if
(
!
privileged_handler_running
)
{
debug
(
1
,
"The privileged thread is dead. Ignoring the command."
);
return
ENOENT
;
}
#ifdef _DEBUG_FORCE
debug
(
4
,
"Sending information to the privileged thread"
);
#endif
cmd
.
action
=
action
;
cmd
.
arg
=
arg
;
#ifdef READWRITE_SIGNALLING
write_inf
(
priv_write_fd
,
buf
,
1
);
#else
pthread_cond_signal
(
&
pthread_cond_privileged
);
#endif
#ifdef _DEBUG_FORCE
debug
(
4
,
"Waiting for the answer"
);
#endif
#ifdef READWRITE_SIGNALLING
read_inf
(
nonp_read_fd
,
buf
,
1
);
#else
pthread_cond_wait
(
&
pthread_cond_action
,
&
pthread_mutex_action_signal
);
#endif
if
(
ret_p
!=
NULL
)
*
ret_p
=
cmd
.
ret
;
errno
=
cmd
.
_errno
;
#ifdef _DEBUG_FORCE
debug
(
4
,
"Unlocking pthread_mutex_action_*"
);
#endif
#ifndef READWRITE_SIGNALLING
pthread_mutex_unlock
(
&
pthread_mutex_action_signal
);
#endif
pthread_mutex_unlock
(
&
pthread_mutex_action_entrance
);
return
0
;
...
...
@@ -677,7 +726,9 @@ int _privileged_fork_execvp(const char *file, char *const argv[])
int
privileged_init
(
ctx_t
*
ctx_p
)
{
#ifdef READWRITE_SIGNALLING
int
pipefds
[
2
];
#endif
#ifdef CAPABILITIES_SUPPORT
if
(
!
ctx_p
->
flags
[
THREADSPLITTING
])
{
...
...
@@ -725,17 +776,25 @@ int privileged_init(ctx_t *ctx_p)
SAFE
(
pthread_cond_init
(
&
pthread_cond_action
,
NULL
),
return
errno
;);
SAFE
(
pthread_cond_init
(
&
pthread_cond_runner
,
NULL
),
return
errno
;);
#ifdef READWRITE_SIGNALLING
SAFE
(
pipe2
(
pipefds
,
O_CLOEXEC
),
return
errno
;);
priv_read_fd
=
pipefds
[
0
];
priv_write_fd
=
pipefds
[
1
];
SAFE
(
pipe2
(
pipefds
,
O_CLOEXEC
),
return
errno
;);
nonp_read_fd
=
pipefds
[
0
];
nonp_write_fd
=
pipefds
[
1
];
#endif
SAFE
(
pthread_mutex_lock
(
&
pthread_mutex_runner
),
return
errno
;);
SAFE
(
pthread_create
(
&
pthread_thread
,
NULL
,
(
void
*
(
*
)(
void
*
))
privileged_handler
,
ctx_p
),
return
errno
);
if
(
ctx_p
->
flags
[
DETACH_NETWORK
]
==
DN_NONPRIVILEGED
)
{
cap_enable
(
CAP_TO_MASK
(
CAP_SYS_ADMIN
)
);
SAFE
(
unshare
(
CLONE_NEWNET
),
return
errno
);
SAFE
(
cap_enable
(
CAP_TO_MASK
(
CAP_SYS_ADMIN
)),
return
errno
;
);
SAFE
(
unshare
(
CLONE_NEWNET
),
return
errno
;
);
}
cap_drop
(
ctx_p
,
0
);
SAFE
(
cap_drop
(
ctx_p
,
0
),
return
errno
;
);
debug
(
4
,
"Waiting for the privileged thread to get prepared"
);
pthread_cond_wait
(
&
pthread_cond_runner
,
&
pthread_mutex_runner
);
...
...
syscalls.h
View file @
d57a446
...
...
@@ -19,3 +19,25 @@
extern
int
pivot_root
(
const
char
*
new_root
,
const
char
*
old_root
);
static
inline
ssize_t
read_inf
(
int
fd
,
void
*
buf
,
size_t
count
)
{
ssize_t
ret
;
errno
=
0
;
do
{
ret
=
read
(
fd
,
buf
,
count
);
}
while
((
ret
==
-
1
)
&&
(
errno
==
EINTR
));
return
ret
;
}
static
inline
ssize_t
write_inf
(
int
fd
,
const
void
*
buf
,
size_t
count
)
{
ssize_t
ret
;
errno
=
0
;
do
{
ret
=
write
(
fd
,
buf
,
count
);
}
while
((
ret
==
-
1
)
&&
(
errno
==
EINTR
));
return
ret
;
}
...
...
Please
register
or
login
to post a comment