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
2015-04-03 14:01:30 +0300
Browse Files
Options
Browse Files
Download
Email Patches
Plain Diff
Commit
0b8659c2b0b9a70f3c8b575bf77843f26fe5daa3
0b8659c2
1 parent
7876ccd0
Added options "--privileged-uid" and "--privileged-gid"
Hide whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
140 additions
and
33 deletions
ctx.h
main.c
man/man1/clsync.1
privileged.c
privileged.h
sync.c
ctx.h
View file @
0b8659c
...
...
@@ -128,6 +128,8 @@ enum flags_enum {
CANCEL_SYSCALLS
=
44
|
OPTION_LONGOPTONLY
,
EXITONSYNCSKIP
=
45
|
OPTION_LONGOPTONLY
,
DETACH_IPC
=
46
|
OPTION_LONGOPTONLY
,
PRIVILEGEDUID
=
47
|
OPTION_LONGOPTONLY
,
PRIVILEGEDGID
=
48
|
OPTION_LONGOPTONLY
,
};
typedef
enum
flags_enum
flags_t
;
...
...
@@ -300,6 +302,8 @@ struct ctx {
size_t
pid_str_len
;
uid_t
uid
;
gid_t
gid
;
uid_t
privileged_uid
;
gid_t
privileged_gid
;
uid_t
synchandler_uid
;
gid_t
synchandler_gid
;
#ifdef CAPABILITIES_SUPPORT
...
...
main.c
View file @
0b8659c
...
...
@@ -79,6 +79,8 @@ static const struct option long_options[] =
{
"pid-file"
,
required_argument
,
NULL
,
PIDFILE
},
{
"uid"
,
required_argument
,
NULL
,
UID
},
{
"gid"
,
required_argument
,
NULL
,
GID
},
{
"privileged-uid"
,
required_argument
,
NULL
,
PRIVILEGEDUID
},
{
"privileged-gid"
,
required_argument
,
NULL
,
PRIVILEGEDGID
},
{
"sync-handler-uid"
,
required_argument
,
NULL
,
SYNCHANDLERUID
},
{
"sync-handler-gid"
,
required_argument
,
NULL
,
SYNCHANDLERGID
},
{
"chroot"
,
required_argument
,
NULL
,
CHROOT
},
...
...
@@ -1047,6 +1049,30 @@ static int parse_parameter(ctx_t *ctx_p, uint16_t param_id, char *arg, paramsour
break
;
}
# endif
case
PRIVILEGEDUID
:
{
struct
passwd
*
pwd
=
getpwnam
(
arg
);
ctx_p
->
flags
[
param_id
]
++
;
if
(
pwd
==
NULL
)
{
ctx_p
->
privileged_uid
=
(
unsigned
int
)
xstrtol
(
arg
,
&
ret
);
break
;
}
ctx_p
->
privileged_uid
=
pwd
->
pw_uid
;
break
;
}
case
PRIVILEGEDGID
:
{
struct
group
*
grp
=
getgrnam
(
arg
);
ctx_p
->
flags
[
param_id
]
++
;
if
(
grp
==
NULL
)
{
ctx_p
->
privileged_gid
=
(
unsigned
int
)
xstrtol
(
arg
,
&
ret
);
break
;
}
ctx_p
->
privileged_gid
=
grp
->
gr_gid
;
break
;
}
case
SYNCHANDLERUID
:
{
struct
passwd
*
pwd
=
getpwnam
(
arg
);
ctx_p
->
flags
[
param_id
]
++
;
...
...
@@ -2339,8 +2365,6 @@ int main(int _argc, char *_argv[]) {
#ifdef CAPABILITIES_SUPPORT
ctx_p
->
flags
[
CAP_PRESERVE
]
=
CAP_PRESERVE_TRY
;
ctx_p
->
caps
=
DEFAULT_PRESERVE_CAPABILITIES
;
ctx_p
->
synchandler_uid
=
getuid
();
ctx_p
->
synchandler_gid
=
getgid
();
ctx_p
->
flags
[
CAPS_INHERIT
]
=
DEFAULT_CAPS_INHERIT
;
ctx_p
->
flags
[
DETACH_IPC
]
=
DEFAULT_DETACH_IPC
;
parse_parameter
(
ctx_p
,
LABEL
,
strdup
(
DEFAULT_LABEL
),
PS_DEFAULTS
);
...
...
@@ -2373,6 +2397,16 @@ int main(int _argc, char *_argv[]) {
if
(
nret
)
ret
=
nret
;
}
if
(
!
ctx_p
->
flags
[
PRIVILEGEDUID
])
ctx_p
->
privileged_uid
=
getuid
();
if
(
!
ctx_p
->
flags
[
PRIVILEGEDGID
])
ctx_p
->
privileged_gid
=
getgid
();
if
(
!
ctx_p
->
flags
[
SYNCHANDLERUID
])
ctx_p
->
synchandler_uid
=
ctx_p
->
privileged_uid
;
if
(
!
ctx_p
->
flags
[
SYNCHANDLERGID
])
ctx_p
->
synchandler_gid
=
ctx_p
->
privileged_gid
;
#ifdef CGROUP_SUPPORT
if
(
ctx_p
->
cg_groupname
==
NULL
)
{
ctx_p
->
cg_groupname
=
parameter_expand
(
ctx_p
,
strdup
(
DEFAULT_CG_GROUPNAME
),
2
,
NULL
,
NULL
,
parameter_get
,
ctx_p
);
...
...
@@ -2819,26 +2853,24 @@ int main(int _argc, char *_argv[]) {
if
(
ctx_p
->
flags
[
GID
])
{
int
rc
;
debug
(
3
,
"Trying to drop gid to %i"
,
ctx_p
->
gid
);
rc
=
setgid
(
ctx_p
->
gid
);
debug
(
3
,
"Trying to drop
effective
gid to %i"
,
ctx_p
->
gid
);
rc
=
set
e
gid
(
ctx_p
->
gid
);
if
(
rc
&&
(
ctx_p
->
flags
[
GID
]
!=
UGID_PRESERVE
))
{
error
(
"Cannot setgid(%u)"
,
ctx_p
->
gid
);
error
(
"Cannot set
e
gid(%u)"
,
ctx_p
->
gid
);
ret
=
errno
;
}
if
(
!
rc
)
debug
(
4
,
"success"
);
}
if
(
ctx_p
->
flags
[
UID
])
{
int
rc
;
debug
(
3
,
"Trying to drop uid to %i"
,
ctx_p
->
uid
);
rc
=
setuid
(
ctx_p
->
uid
);
debug
(
3
,
"Trying to drop
effective
uid to %i"
,
ctx_p
->
uid
);
rc
=
set
e
uid
(
ctx_p
->
uid
);
if
(
rc
&&
(
ctx_p
->
flags
[
UID
]
!=
UGID_PRESERVE
))
{
error
(
"Cannot setuid(%u)"
,
ctx_p
->
uid
);
error
(
"Cannot set
e
uid(%u)"
,
ctx_p
->
uid
);
ret
=
errno
;
}
if
(
!
rc
)
debug
(
4
,
"success"
);
}
if
(
main_statusfile_f
==
NULL
&&
ctx_p
->
statusfile
!=
NULL
)
{
...
...
man/man1/clsync.1
View file @
0b8659c
...
...
@@ -1260,6 +1260,26 @@ found), otherwise the option is not set by default;
.PP
.RE
.B \-\-privileged\-uid
.I sync\-handler\-uid
.RS
An user ID to be used for the privileged process
.BR "" "(see " "--splitting=process" ")".
The default value is "$UID".
.PP
.RE
.B \-\-privileged\-gid
.I sync\-handler\-gid
.RS
A group ID to be used for the privileged process
.BR "" "(see " "--splitting=process" ")".
The default value is "$GID".
.PP
.RE
.B \-\-sync\-handler\-uid
.I sync\-handler\-uid
.RS
...
...
@@ -1269,7 +1289,8 @@ An user ID to be used for
See
.BR \-\-preserve\-capabilities .
The default value is "$UID".
The default value is same as for
.BR \-\-privileged-uid .
.PP
.RE
...
...
@@ -1282,7 +1303,8 @@ A group ID to be used for
See
.BR \-\-preserve\-capabilities .
The default value is "$GID".
The default value is same as for
.BR \-\-privileged-gid .
.PP
.RE
...
...
privileged.c
View file @
0b8659c
...
...
@@ -133,6 +133,8 @@ int nonprivileged_seccomp_init(ctx_t *ctx_p) {
.
filter
=
filter_w_mprotect_table
,
};
debug
(
5
,
"enabling the seccomp"
);
filter_p
=
(
ctx_p
->
flags
[
PERMIT_MPROTECT
]
?
&
filter_w_mprotect
:
&
filter
);
SAFE
(
prctl
(
PR_SET_NO_NEW_PRIVS
,
1
,
0
,
0
,
0
),
return
-
1
);
...
...
@@ -143,7 +145,7 @@ int nonprivileged_seccomp_init(ctx_t *ctx_p) {
#endif
int
(
*
privileged_fork_execvp
)(
const
char
*
file
,
char
*
const
argv
[]);
int
(
*
privileged_kill_child
)(
pid_t
pid
,
int
sig
);
int
(
*
privileged_kill_child
)(
pid_t
pid
,
int
sig
,
char
ignoreerrors
);
#ifdef CAPABILITIES_SUPPORT
pid_t
helper_pid
=
0
;
...
...
@@ -219,6 +221,7 @@ struct pa_fork_execvp_arg {
struct
pa_kill_child_arg
{
pid_t
pid
;
int
signal
;
char
ignoreerrors
;
};
struct
pa_waitpid_arg
{
...
...
@@ -444,13 +447,14 @@ int cap_drop(ctx_t *ctx_p, __u32 caps) {
}
#endif
int
__privileged_kill_child_itself
(
pid_t
child_pid
,
int
signal
)
{
int
__privileged_kill_child_itself
(
pid_t
child_pid
,
int
signal
,
char
ignoreerrors
)
{
// Checking if it's a child
if
(
waitpid
(
child_pid
,
NULL
,
WNOHANG
)
>=
0
)
{
debug
(
3
,
"Sending signal %u to child process with pid %u."
,
signal
,
child_pid
);
if
(
kill
(
child_pid
,
signal
))
{
error
(
"Got error while kill(%u, %u)"
,
child_pid
,
signal
);
if
(
!
ignoreerrors
)
error
(
"Got error while kill(%u, %u)"
,
child_pid
,
signal
);
return
errno
;
}
...
...
@@ -534,14 +538,18 @@ int privileged_execvp_check_arguments(struct pa_options *opts, const char *u_fil
critical_on
(
!
argc
);
// Checking the execution file
if
(
pa_strcmp
(
argv
[
0
],
u_file
,
isexpanded
[
0
]))
continue
;
if
(
pa_strcmp
(
argv
[
0
],
u_file
,
isexpanded
[
0
]))
{
debug
(
1
,
"The file to be executed didn't match (argv[0] != u_file):
\"
%s
\"
!=
\"
%s
\"
"
,
argv
[
0
],
u_file
);
break
;
}
// Checking arguments
i
=
1
;
while
(
i
<
argc
)
{
if
(
pa_strcmp
(
argv
[
i
],
u_argv
[
i
],
isexpanded
[
i
]))
if
(
pa_strcmp
(
argv
[
i
],
u_argv
[
i
],
isexpanded
[
i
]))
{
debug
(
1
,
"An argument #%i didn't match (argv[%i] != u_argv[%i]):
\"
%s
\"
!=
\"
%s
\"
"
,
argv
[
i
],
argv
[
i
]);
break
;
}
i
++
;
}
...
...
@@ -577,6 +585,7 @@ int privileged_execvp_check_arguments(struct pa_options *opts, const char *u_fil
}
}
debug
(
1
,
"a_i == %i; SHARGS_MAX == %i; u_argc == %i"
,
SHARGS_MAX
,
a_i
,
u_argc
);
critical
(
"Arguments are wrong. This should happend only on hacking attack."
);
return
EPERM
;
}
...
...
@@ -1017,8 +1026,16 @@ int privileged_handler(ctx_t *ctx_p)
error
(
"Cannot fork()."
);
break
;
case
0
:
debug
(
4
,
"setgid(%u) == %i"
,
exec_gid
,
setgid
(
exec_gid
));
debug
(
4
,
"setuid(%u) == %i"
,
exec_uid
,
setuid
(
exec_uid
));
#ifdef ANTIPARANOID
if
(
ctx_p
->
privileged_gid
!=
exec_gid
)
#endif
debug
(
4
,
"setgid(%u) == %i"
,
exec_gid
,
setgid
(
exec_gid
));
#ifdef ANTIPARANOID
if
(
ctx_p
->
privileged_uid
!=
exec_uid
)
#endif
debug
(
4
,
"setuid(%u) == %i"
,
exec_uid
,
setuid
(
exec_uid
));
debug
(
3
,
"execvp(
\"
%s
\"
, argv)"
,
file
);
exit
(
execvp
(
file
,
argv
));
}
...
...
@@ -1029,7 +1046,7 @@ int privileged_handler(ctx_t *ctx_p)
case
PA_KILL_CHILD
:
{
debug
(
20
,
"PA_KILL_CHILD"
);
struct
pa_kill_child_arg
*
arg_p
=
(
void
*
)
&
cmd_p
->
arg
.
kill_child
;
cmd_ret_p
->
ret
=
(
void
*
)(
long
)
__privileged_kill_child_itself
(
arg_p
->
pid
,
arg_p
->
signal
);
cmd_ret_p
->
ret
=
(
void
*
)(
long
)
__privileged_kill_child_itself
(
arg_p
->
pid
,
arg_p
->
signal
,
arg_p
->
ignoreerrors
);
break
;
}
# ifdef CGROUP_SUPPORT
...
...
@@ -1544,12 +1561,13 @@ int __privileged_fork_setuid_execvp_threadsplit(
return
(
long
)
ret
;
}
int
__privileged_kill_child_wrapper
(
pid_t
pid
,
int
signal
)
int
__privileged_kill_child_wrapper
(
pid_t
pid
,
int
signal
,
char
ignoreerrors
)
{
void
*
ret
=
(
void
*
)(
long
)
-
1
;
cmd_p
->
arg
.
kill_child
.
pid
=
pid
;
cmd_p
->
arg
.
kill_child
.
signal
=
signal
;
cmd_p
->
arg
.
kill_child
.
pid
=
pid
;
cmd_p
->
arg
.
kill_child
.
signal
=
signal
;
cmd_p
->
arg
.
kill_child
.
ignoreerrors
=
ignoreerrors
;
privileged_action
(
# ifdef HL_LOCK_TRIES_AUTO
...
...
@@ -1781,14 +1799,43 @@ int privileged_init(ctx_t *ctx_p)
// Running the privileged helper
SAFE
(
(
helper_pid
=
fork_helper
())
==
-
1
,
return
errno
);
if
(
!
helper_pid
)
if
(
!
helper_pid
)
{
if
(
ctx_p
->
privileged_gid
!=
ctx_p
->
gid
)
{
// SAFE ( cap_enable(CAP_TO_MASK(CAP_SETGID)), return errno; );
debug
(
3
,
"[privileged] Trying to set real gid to %i (ctx_p->privileged_gid)"
,
ctx_p
->
privileged_gid
);
SAFE
(
setgid
(
ctx_p
->
privileged_gid
),
return
errno
);
}
if
(
ctx_p
->
privileged_uid
!=
ctx_p
->
uid
)
{
// SAFE ( cap_enable(CAP_TO_MASK(CAP_SETUID)), return errno; );
debug
(
3
,
"[privileged] Trying to set real uid to %i (ctx_p->privileged_uid)"
,
ctx_p
->
privileged_uid
);
SAFE
(
setuid
(
ctx_p
->
privileged_uid
),
return
errno
);
}
exit
(
privileged_handler
(
ctx_p
));
}
break
;
}
default:
critical
(
"Invalid ctx_p->flags[SPLITTING]: %i"
,
ctx_p
->
flags
[
SPLITTING
]);
}
if
(
ctx_p
->
flags
[
GID
]
||
ctx_p
->
flags
[
UID
])
SAFE
(
seteuid
(
0
),
return
errno
);
if
(
ctx_p
->
flags
[
GID
])
{
SAFE
(
setegid
(
0
),
return
errno
);
debug
(
3
,
"[non-privileged] Trying to drop real gid %i (ctx_p->gid)"
,
getgid
(),
ctx_p
->
gid
);
SAFE
(
setgid
(
ctx_p
->
gid
),
return
errno
);
}
if
(
ctx_p
->
flags
[
UID
])
{
debug
(
3
,
"[non-privileged] Trying to drop real uid %i (ctx_p->uid)"
,
getuid
(),
ctx_p
->
uid
);
SAFE
(
setuid
(
ctx_p
->
uid
),
return
errno
);
}
# ifdef HL_LOCKS
if
(
ncpus
==
1
)
hl_shutdown
(
HLLOCK_HANDLER
);
...
...
@@ -1883,9 +1930,10 @@ int privileged_deinit(ctx_t *ctx_p)
case
SM_PROCESS
:
{
int
status
;
if
(
!
ctx_p
->
flags
[
SECCOMP_FILTER
])
{
__privileged_kill_child_itself
(
helper_pid
,
SIGKILL
);
debug
(
9
,
"waitpid(%u, ...)"
,
helper_pid
);
waitpid
(
helper_pid
,
&
status
,
0
);
if
(
!
__privileged_kill_child_itself
(
helper_pid
,
SIGKILL
,
1
))
{
debug
(
9
,
"waitpid(%u, ...)"
,
helper_pid
);
waitpid
(
helper_pid
,
&
status
,
0
);
}
}
shm_free
((
void
*
)
cmd_p
);
shm_free
((
void
*
)
cmd_ret_p
);
...
...
privileged.h
View file @
0b8659c
...
...
@@ -123,7 +123,8 @@ extern int privileged_check();
extern
int
(
*
_privileged_kill_child
)(
pid_t
pid
,
int
sig
int
sig
,
char
ignoreerrors
);
extern
int
(
*
_privileged_fork_execvp
)(
...
...
sync.c
View file @
0b8659c
...
...
@@ -3673,15 +3673,15 @@ int sync_sighandler(sighandler_arg_t *sighandler_arg_p) {
while
(
ctx_p
->
children
)
{
// Killing children if non-pthread mode or/and (mode=="so" or mode=="rsyncso")
pid_t
child_pid
=
ctx_p
->
child_pid
[
--
ctx_p
->
children
];
if
(
privileged_kill_child
(
child_pid
,
signal
)
==
ENOENT
)
if
(
privileged_kill_child
(
child_pid
,
signal
,
0
)
==
ENOENT
)
continue
;
if
(
signal
!=
SIGQUIT
)
if
(
privileged_kill_child
(
child_pid
,
SIGQUIT
)
==
ENOENT
)
if
(
privileged_kill_child
(
child_pid
,
SIGQUIT
,
0
)
==
ENOENT
)
continue
;
if
(
signal
!=
SIGTERM
)
if
(
privileged_kill_child
(
child_pid
,
SIGTERM
)
==
ENOENT
)
if
(
privileged_kill_child
(
child_pid
,
SIGTERM
,
0
)
==
ENOENT
)
continue
;
if
(
privileged_kill_child
(
child_pid
,
SIGKILL
)
==
ENOENT
)
if
(
privileged_kill_child
(
child_pid
,
SIGKILL
,
0
)
==
ENOENT
)
continue
;
}
break
;
...
...
Please
register
or
login
to post a comment