|
@@ -18,6 +18,12 @@
|
|
|
#include <string.h>
|
|
|
#include <elf.h>
|
|
|
#include <bits/uClibc_page.h>
|
|
|
+#include <paths.h>
|
|
|
+#include <unistd.h>
|
|
|
+#include <asm/errno.h>
|
|
|
+#include <fcntl.h>
|
|
|
+#include <sys/stat.h>
|
|
|
+#include <sys/sysmacros.h>
|
|
|
#ifdef __UCLIBC_PROPOLICE__
|
|
|
extern void __guard_setup(void);
|
|
|
#endif
|
|
@@ -46,19 +52,58 @@ extern void weak_function __pthread_initialize_minimal(void);
|
|
|
* Note: Apparently we must initialize __environ to ensure that the weak
|
|
|
* environ symbol is also included.
|
|
|
*/
|
|
|
+char **__environ = 0;
|
|
|
+weak_alias(__environ, environ);
|
|
|
|
|
|
size_t __pagesize = 0;
|
|
|
-char **__environ = 0;
|
|
|
const char *__progname = 0;
|
|
|
-weak_alias(__environ, environ);
|
|
|
|
|
|
-
|
|
|
-#if 0
|
|
|
-extern int _dl_secure;
|
|
|
-int __secure = 0;
|
|
|
-weak_alias(__secure, _dl_secure);
|
|
|
+
|
|
|
+#ifndef O_NOFOLLOW
|
|
|
+# define O_NOFOLLOW 0
|
|
|
#endif
|
|
|
|
|
|
+extern int __libc_fcntl(int fd, int cmd, ...);
|
|
|
+extern int __libc_open(const char *file, int flags, ...);
|
|
|
+
|
|
|
+static void __check_one_fd(int fd, int mode)
|
|
|
+{
|
|
|
+
|
|
|
+ if (unlikely(__libc_fcntl(fd, F_GETFD)==-1 && *(__errno_location())==EBADF))
|
|
|
+ {
|
|
|
+
|
|
|
+ struct stat st;
|
|
|
+ int nullfd = __libc_open(_PATH_DEVNULL, mode);
|
|
|
+
|
|
|
+ * that is in fact the device that we have opened and not
|
|
|
+ * some other wierd file... */
|
|
|
+ if ( (nullfd!=fd) || fstat(fd, &st) || !S_ISCHR(st.st_mode) ||
|
|
|
+ (st.st_rdev != makedev(1, 3)))
|
|
|
+ {
|
|
|
+
|
|
|
+ while (1) {
|
|
|
+ abort();
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+static int __check_suid(void)
|
|
|
+{
|
|
|
+ uid_t uid, euid;
|
|
|
+ gid_t gid, egid;
|
|
|
+
|
|
|
+ uid = getuid();
|
|
|
+ euid = geteuid();
|
|
|
+ gid = getgid();
|
|
|
+ egid = getegid();
|
|
|
+
|
|
|
+ if(uid == euid && gid == egid) {
|
|
|
+ return 0;
|
|
|
+ }
|
|
|
+ return 1;
|
|
|
+}
|
|
|
+
|
|
|
|
|
|
|
|
|
*
|
|
@@ -94,16 +139,6 @@ void __uClibc_init(void)
|
|
|
__pthread_initialize_minimal();
|
|
|
#endif
|
|
|
|
|
|
-
|
|
|
-#if 0
|
|
|
-
|
|
|
- * where the standard file descriptors are not opened. We have
|
|
|
- * to do this only for statically linked applications since
|
|
|
- * otherwise the dynamic loader did the work already. */
|
|
|
- if (unlikely (__secure!=NULL))
|
|
|
- __libc_check_standard_fds ();
|
|
|
-#endif
|
|
|
-
|
|
|
#ifdef __UCLIBC_HAS_LOCALE__
|
|
|
|
|
|
if (likely(_locale_init!=NULL))
|
|
@@ -161,7 +196,21 @@ __uClibc_start_main(int argc, char **argv, char **envp,
|
|
|
}
|
|
|
aux_dat += 2;
|
|
|
}
|
|
|
+
|
|
|
+
|
|
|
__pagesize = (auxvt[AT_PAGESZ].a_un.a_val)? auxvt[AT_PAGESZ].a_un.a_val : PAGE_SIZE;
|
|
|
+
|
|
|
+
|
|
|
+ * stderr file descriptors are not already opened. */
|
|
|
+ if ((auxvt[AT_UID].a_un.a_val==-1 && __check_suid()) ||
|
|
|
+ (auxvt[AT_UID].a_un.a_val != -1 &&
|
|
|
+ (auxvt[AT_UID].a_un.a_val != auxvt[AT_EUID].a_un.a_val ||
|
|
|
+ auxvt[AT_GID].a_un.a_val != auxvt[AT_EGID].a_un.a_val)))
|
|
|
+ {
|
|
|
+ __check_one_fd (STDIN_FILENO, O_RDONLY | O_NOFOLLOW);
|
|
|
+ __check_one_fd (STDOUT_FILENO, O_RDWR | O_NOFOLLOW);
|
|
|
+ __check_one_fd (STDERR_FILENO, O_RDWR | O_NOFOLLOW);
|
|
|
+ }
|
|
|
#endif
|
|
|
|
|
|
__progname = *argv;
|