redmine

Added option "--add-permitted-hook-files" to make exceptions for "--check-execvp-arguments"

... ... @@ -32,6 +32,7 @@
#define MAXCHILDREN (1<<8)
#define MAXMOUNTPOINTS (1<<8)
#define MAXPERMITTEDHOOKFILES (1<<8)
#ifdef __CLSYNC_COMMON_H
# if INOTIFY_SUPPORT
... ...
... ... @@ -107,6 +107,7 @@ enum flags_enum {
PIVOT_ROOT = 31|OPTION_LONGOPTONLY,
DETACH_NETWORK = 32|OPTION_LONGOPTONLY,
DETACH_MISCELLANEA = 33|OPTION_LONGOPTONLY,
ADDPERMITTEDHOOKFILES = 34|OPTION_LONGOPTONLY,
};
typedef enum flags_enum flags_t;
... ... @@ -325,6 +326,11 @@ struct ctx {
char *chroot_dir;
#ifdef CAPABILITIES_SUPPORT
char *permitted_hookfile[MAXPERMITTEDHOOKFILES+1];
int permitted_hookfiles;
#endif
#ifdef GETMNTENT_SUPPORT
char *mountpoint[MAXMOUNTPOINTS+1];
int mountpoints;
... ...
... ... @@ -86,6 +86,7 @@ static const struct option long_options[] =
#ifdef CAPABILITIES_SUPPORT
{"thread-splitting", optional_argument, NULL, THREADSPLITTING},
{"check-execvp-args", optional_argument, NULL, CHECK_EXECVP_ARGS},
{"add-permitted-hook-files",required_argument, NULL, ADDPERMITTEDHOOKFILES},
#endif
#ifdef GETMNTENT_SUPPORT
{"mountpoints", optional_argument, NULL, MOUNTPOINTS},
... ... @@ -809,6 +810,50 @@ int parse_parameter(ctx_t *ctx_p, uint16_t param_id, char *arg, paramsource_t pa
break;
}
#endif
#ifdef CAPABILITIES_SUPPORT
case ADDPERMITTEDHOOKFILES: {
char *ptr;
if (paramsource == PS_CONTROL) {
warning("Cannot change \"add-permitted-hook-files\" in run-time. Ignoring.");
return 0;
}
while (ctx_p->permitted_hookfiles)
free(ctx_p->permitted_hookfile[--ctx_p->permitted_hookfiles]);
ptr = arg;
while (1) {
char *end = strchr(ptr, ',');
if (end != NULL)
*end = 0;
if (!*ptr) {
while (ctx_p->permitted_hookfiles)
free(ctx_p->permitted_hookfile[--ctx_p->permitted_hookfiles]);
if (end != NULL)
ptr = &end[1];
continue;
}
if (ctx_p->permitted_hookfiles >= MAXPERMITTEDHOOKFILES) {
errno = EINVAL;
error("Too many permitted hook files");
return errno;
}
ctx_p->permitted_hookfile[ctx_p->permitted_hookfiles++] = strdup(ptr);
if (end == NULL)
break;
*end = ',';
ptr = &end[1];
}
break;
}
#endif
#ifdef GETMNTENT_SUPPORT
case MOUNTPOINTS: {
char *ptr;
... ... @@ -2197,7 +2242,7 @@ int main(int argc, char *argv[]) {
struct mntent *ent;
FILE *ent_f;
ent_f = NULL; // Anti-warning, gcc-4.8.2
ent_f = NULL;
if (ctx_p->mountpoints) {
// Openning the file with mount list
ent_f = setmntent("/proc/mounts", "r");
... ...
... ... @@ -441,8 +441,34 @@ syscalls on every dir and can reduce performance.
Is not set by default.
.RE
.B \-\-socket
.I socket\-path
.RS
Create a control socket by path
.IR socket\-path .
This's very experimental feature.
Is not set by default.
.RE
.B \-\-socket\-own
.I socket\-owner\-user[:socket\-owner\-group]
.RS
Sets the control socket owner user (and group).
Is not set by default
.RE
.B \-\-socket\-mod
.I socket\-mode
.RS
Sets the control socket mode [see
.BR chmod (2)].
Is not set by default.
.RE
.PP
.B \-c, \-\-cluster\-iface
.I interface\-ip
.RS
... ... @@ -1201,6 +1227,22 @@ and hook file paths.
Is not set by default.
.RE
.B \-\-add\-permitted\-hook\-files
.I [hook\-path0,[hook\-path1[,...]]]
.RS
.B [Requires \-\-add\-permitted\-hook\-files]
Adds paths to the list of permitted hook paths to bypass
.B \-\-check\-execvp\-arguments
checks. It may be required if you're going to change the hooks in run-time
using
.B \-\-custom\-signals
or
.BR \-\-socket .
Is not set by default.
.RE
.B \-\-chroot
.I chroot\-directory
.RS
... ...
... ... @@ -110,6 +110,8 @@ struct pa_options {
char *label;
char *exithookfile;
char *preexithookfile;
char *permitted_hookfile[MAXPERMITTEDHOOKFILES+1];
int permitted_hookfiles;
};
FTS *(*privileged_fts_open) (
... ... @@ -288,8 +290,10 @@ int privileged_execvp_check_arguments(struct pa_options *opts, const char *u_fil
if (a_i < SHARGS_MAX)
return 0;
if ((opts->exithookfile != NULL) || (opts->preexithookfile != NULL))
if (u_argc == 2) {
if (u_argc == 2) {
int i;
if ((opts->exithookfile != NULL) || (opts->preexithookfile != NULL)) {
if (!strcmp(opts->label, u_argv[1])) {
if (opts->exithookfile != NULL)
if (!strcmp(opts->exithookfile, u_file))
... ... @@ -300,6 +304,13 @@ int privileged_execvp_check_arguments(struct pa_options *opts, const char *u_fil
}
}
while (i < opts->permitted_hookfiles) {
if (!strcmp(opts->permitted_hookfile[i], u_file))
return 0;
i++;
}
}
critical("Arguments are wrong. This should happend only on hacking attack.");
return EPERM;
}
... ... @@ -349,6 +360,16 @@ int pa_setup(struct pa_options *opts, ctx_t *ctx_p, uid_t *exec_uid_p, gid_t *ex
if (ctx_p->preexithookfile != NULL)
opts->preexithookfile = strdup(ctx_p->preexithookfile);
{
int i = 0;
while (i < ctx_p->permitted_hookfiles) {
opts->permitted_hookfile[i] = strdup(ctx_p->permitted_hookfile[i]);
i++;
}
opts->permitted_hookfile[i] = NULL;
opts->permitted_hookfiles = i;
}
return 0;
}
... ...