Lines 736-744
execve(const char *filename, char *const
Link Here
|
736 |
int old_errno = errno; |
736 |
int old_errno = errno; |
737 |
int result = -1; |
737 |
int result = -1; |
738 |
int count = 0; |
738 |
int count = 0; |
|
|
739 |
int env_len = 0; |
739 |
char canonic[SB_PATH_MAX]; |
740 |
char canonic[SB_PATH_MAX]; |
740 |
char *old_envp = NULL; |
741 |
char **my_env = NULL; |
741 |
char *new_envp = NULL; |
742 |
/* We limit the size LD_PRELOAD can be here, but it should be enough */ |
|
|
743 |
char tmp_str[4096]; |
742 |
|
744 |
|
743 |
canonicalize_int(filename, canonic); |
745 |
canonicalize_int(filename, canonic); |
744 |
|
746 |
|
Lines 747-782
execve(const char *filename, char *const
Link Here
|
747 |
while (envp[count] != NULL) { |
749 |
while (envp[count] != NULL) { |
748 |
if (strstr(envp[count], "LD_PRELOAD=") == envp[count]) { |
750 |
if (strstr(envp[count], "LD_PRELOAD=") == envp[count]) { |
749 |
if (NULL != strstr(envp[count], sandbox_lib)) { |
751 |
if (NULL != strstr(envp[count], sandbox_lib)) { |
|
|
752 |
my_env = (char **) envp; |
750 |
break; |
753 |
break; |
751 |
} else { |
754 |
} else { |
|
|
755 |
int i = 0; |
752 |
const int max_envp_len = |
756 |
const int max_envp_len = |
753 |
strlen(envp[count]) + strlen(sandbox_lib) + 1; |
757 |
strlen(envp[count]) + strlen(sandbox_lib) + 1; |
754 |
|
758 |
|
755 |
/* Backup envp[count], and set it to our own one which |
759 |
/* Fail safe ... */ |
756 |
* contains sandbox_lib */ |
760 |
if (max_envp_len > 4096) { |
757 |
old_envp = envp[count]; |
761 |
fprintf(stderr, "sandbox: max_envp_len too big!\n"); |
758 |
new_envp = strndupa(old_envp, max_envp_len - 1); |
762 |
errno = ENOMEM; |
|
|
763 |
return result; |
764 |
} |
765 |
|
766 |
/* Calculate envp size */ |
767 |
my_env = (char **) envp; |
768 |
do |
769 |
env_len += 1; |
770 |
while (*my_env++); |
771 |
|
772 |
my_env = (char **) malloc((env_len + 2) * sizeof (char *)); |
773 |
if (NULL == my_env) { |
774 |
errno = ENOMEM; |
775 |
return result; |
776 |
} |
777 |
/* Copy envp to my_env */ |
778 |
do |
779 |
my_env[i] = envp[i]; |
780 |
while (envp[i++]); |
781 |
|
782 |
/* Set tmp_str to envp[count] */ |
783 |
strncpy(tmp_str, envp[count], max_envp_len - 1); |
759 |
|
784 |
|
760 |
/* LD_PRELOAD already have variables other than sandbox_lib, |
785 |
/* LD_PRELOAD already have variables other than sandbox_lib, |
761 |
* thus we have to add sandbox_lib via a white space. */ |
786 |
* thus we have to add sandbox_lib seperated via a whitespace. */ |
762 |
if (0 != strcmp(envp[count], "LD_PRELOAD=")) { |
787 |
if (0 != strncmp(envp[count], "LD_PRELOAD=", max_envp_len - 1)) { |
763 |
strncpy(new_envp + strlen(old_envp), ":", |
788 |
strncat(tmp_str, " ", max_envp_len - strlen(tmp_str)); |
764 |
max_envp_len - strlen(new_envp)); |
789 |
strncat(tmp_str, sandbox_lib, max_envp_len - strlen(tmp_str)); |
765 |
strncpy(new_envp + strlen(old_envp) + 1, sandbox_lib, |
|
|
766 |
max_envp_len - strlen(new_envp)); |
767 |
} else { |
790 |
} else { |
768 |
strncpy(new_envp + |
791 |
strncat(tmp_str, sandbox_lib, max_envp_len - strlen(tmp_str)); |
769 |
strlen(old_envp), sandbox_lib, |
|
|
770 |
max_envp_len - strlen(new_envp)); |
771 |
} |
792 |
} |
772 |
|
793 |
|
773 |
/* Valid string? */ |
794 |
/* Valid string? */ |
774 |
new_envp[max_envp_len] = '\0'; |
795 |
tmp_str[max_envp_len] = '\0'; |
775 |
|
796 |
|
776 |
/* envp[count] = new_envp; |
797 |
/* Ok, replace my_env[count] with our version that contains |
777 |
* |
798 |
* sandbox_lib ... */ |
778 |
* Get rid of the "read-only" warnings */ |
799 |
my_env[count] = tmp_str; |
779 |
memcpy((void *) &envp[count], &new_envp, sizeof (new_envp)); |
|
|
780 |
|
800 |
|
781 |
break; |
801 |
break; |
782 |
} |
802 |
} |
Lines 786-802
execve(const char *filename, char *const
Link Here
|
786 |
|
806 |
|
787 |
errno = old_errno; |
807 |
errno = old_errno; |
788 |
check_dlsym(execve); |
808 |
check_dlsym(execve); |
789 |
result = true_execve(filename, argv, envp); |
809 |
result = true_execve(filename, argv, my_env); |
790 |
old_errno = errno; |
810 |
old_errno = errno; |
791 |
|
811 |
|
792 |
if (old_envp) { |
812 |
if (my_env) { |
793 |
/* Restore envp[count] again. |
813 |
free(my_env); |
794 |
* |
814 |
my_env = NULL; |
795 |
* envp[count] = old_envp; */ |
|
|
796 |
memcpy((void *) &envp[count], &old_envp, sizeof (old_envp)); |
797 |
old_envp = NULL; |
798 |
} |
799 |
} |
815 |
} |
|
|
816 |
} |
800 |
|
817 |
|
801 |
errno = old_errno; |
818 |
errno = old_errno; |
802 |
|
819 |
|