Exemple #1
0
static int pthread_initialize_manager(void)
{
	int manager_pipe[2];

	/* Setup stack for thread manager */
	__pthread_manager_thread_bos = malloc(THREAD_MANAGER_STACK_SIZE);
	if (__pthread_manager_thread_bos == NULL) 
		return -1;
	
	pthread_manager_thread_tos =
		__pthread_manager_thread_bos + THREAD_MANAGER_STACK_SIZE;
    /* Setup pipe to communicate with thread manager */
	if (pipe(manager_pipe) == -1) {
		free(__pthread_manager_thread_bos);
		return -1;
    }
	__pthread_manager_request = manager_pipe[1]; /* writing end */
	__pthread_manager_reader = manager_pipe[0]; /* reading end */
	/* Start the thread manager */
	if (__clone(__pthread_manager,
	          	__pthread_manager_thread_tos,
				CLONE_VM | CLONE_FS | CLONE_FILES | CLONE_SIGHAND,
				(void *)(long)manager_pipe[0]) == -1) {
		free(__pthread_manager_thread_bos);
		__libc_close(manager_pipe[0]);
    	__libc_close(manager_pipe[1]);
	    __pthread_manager_request = -1;
		return -1;
	}
	return 0;
}
Exemple #2
0
FILE*__stdio_init_file(int fd,int closeonerror,int mode) {
  FILE *tmp=(FILE*)malloc(sizeof(FILE));
  if (!tmp) goto err_out;
  tmp->buf=(char*)malloc(BUFSIZE);
  if (!tmp->buf) {
    free(tmp);
err_out:
    if (closeonerror) __libc_close(fd);
    errno=ENOMEM;
    return 0;
  }
  tmp->fd=fd;
  tmp->bm=0;
  tmp->bs=0;
  tmp->buflen=BUFSIZE;
  {
    struct stat st;
    fstat(fd,&st);
    tmp->flags=(S_ISFIFO(st.st_mode))?FDPIPE:0;
  }
  switch (mode&3) {
  case O_RDWR: tmp->flags|=CANWRITE;	/* fall through */
  case O_RDONLY: tmp->flags|=CANREAD|BUFINPUT; break;
  case O_WRONLY: tmp->flags|=CANWRITE;
  }
  tmp->popen_kludge=0;
  if (__stdio_atexit==0) {
    __stdio_atexit=1;
    atexit(__stdio_flushall);
  }
  tmp->next=__stdio_root;
  __stdio_root=tmp;
  tmp->ungotten=0;
  return tmp;
}
Exemple #3
0
static void openlog_intern(int option, int facility)
{
  LogStat = option;
  if (facility && ((facility & ~LOG_FACMASK) == 0))
    LogFacility = facility;

  /* yep, there is a continue inside ;) */
  while(1) {
    if (LogFile == -1) {
      SyslogAddr.sa_family = AF_UNIX;
      strncpy(SyslogAddr.sa_data, _PATH_LOG, sizeof(SyslogAddr.sa_data));
      if (LogStat & LOG_NDELAY)
      {
	if ((LogFile = socket(AF_UNIX, LogType, 0)) == -1) return;
	__libc_fcntl(LogFile, F_SETFD, 1);
      }
    }
    if ((LogFile != -1) && !connected) {
      int old_errno=errno;
      if(connect(LogFile, &SyslogAddr, sizeof(SyslogAddr)) == -1) {
	int saved_errno=errno;
	__libc_close(LogFile);
	LogFile = -1;
	if((LogType == SOCK_DGRAM) && (saved_errno == EPROTOTYPE)) {
	  /* retry with SOCK_STREAM instead of SOCK_DGRAM */
	  LogType = SOCK_STREAM;
	  errno=old_errno;
	  continue;
	}
      }
      else connected = 1;
    }
    break;
  }
}
Exemple #4
0
static void closelog_intern(void)
{
  if (!connected) return;
  __libc_close(LogFile);
  LogFile = -1;
  connected = 0;
}
Exemple #5
0
void __guard_setup(void)
{
	size_t size;

	if (__guard != 0UL)
		return;

	/* Start with the "terminator canary". */
	__guard = 0xFF0A0D00UL;

#ifndef __SSP_QUICK_CANARY__
# ifdef __SSP_USE_ERANDOM__
	{
		int mib[3];
		/* Random is another depth in Linux, hence an array of 3. */
		mib[0] = CTL_KERN;
		mib[1] = KERN_RANDOM;
		mib[2] = RANDOM_ERANDOM;

		size = sizeof(unsigned long);
		if (__sysctl(mib, 3, &__guard, &size, NULL, 0) != (-1))
			if (__guard != 0UL)
				return;
	}
# endif /* ifdef __SSP_USE_ERANDOM__ */
	/* 
	 * Attempt to open kernel pseudo random device if one exists before 
	 * opening urandom to avoid system entropy depletion.
	 */
	{
		int fd;

# ifdef __SSP_USE_ERANDOM__
		if ((fd = __libc_open("/dev/erandom", O_RDONLY)) == (-1))
# endif
			fd = __libc_open("/dev/urandom", O_RDONLY);
		if (fd != (-1)) {
			size = __libc_read(fd, (char *) &__guard, sizeof(__guard));
			__libc_close(fd);
			if (size == sizeof(__guard))
				return;
		}
	}
#endif /* ifndef __SSP_QUICK_CANARY__ */

	/* Everything failed? Or we are using a weakened model of the 
	 * terminator canary */
	{
		struct timeval tv;
		__gettimeofday(&tv, NULL);
		__guard ^= tv.tv_usec ^ tv.tv_sec;
	}
}
void __pthread_reset_main_thread()
{
  pthread_descr self = thread_self();

  if (__pthread_manager_request != -1) {
    /* Free the thread manager stack */
    free(__pthread_manager_thread_bos);
    __pthread_manager_thread_bos = __pthread_manager_thread_tos = NULL;
    /* Close the two ends of the pipe */
    __libc_close(__pthread_manager_request);
    __libc_close(__pthread_manager_reader);
    __pthread_manager_request = __pthread_manager_reader = -1;
  }

  /* Update the pid of the main thread */
  THREAD_SETMEM(self, p_pid, __getpid());
  /* Make the forked thread the main thread */
  __pthread_main_thread = self;
  THREAD_SETMEM(self, p_nextlive, self);
  THREAD_SETMEM(self, p_prevlive, self);
  /* Now this thread modifies the global variables.  */
  THREAD_SETMEM(self, p_errnop, &_errno);
  THREAD_SETMEM(self, p_h_errnop, &_h_errno);
}
Exemple #7
0
int __pthread_initialize_manager(void)
{
  int manager_pipe[2];
  int pid;
  struct pthread_request request;

#ifndef HAVE_Z_NODELETE
  if (__builtin_expect (&__dso_handle != NULL, 1))
    __cxa_atexit ((void (*) (void *)) pthread_atexit_retcode, NULL,
		  __dso_handle);
#endif

  if (__pthread_max_stacksize == 0)
    __pthread_init_max_stacksize ();
  /* If basic initialization not done yet (e.g. we're called from a
     constructor run before our constructor), do it now */
  if (__pthread_initial_thread_bos == NULL) pthread_initialize();
  /* Setup stack for thread manager */
  __pthread_manager_thread_bos = malloc(THREAD_MANAGER_STACK_SIZE);
  if (__pthread_manager_thread_bos == NULL) return -1;
  __pthread_manager_thread_tos =
    __pthread_manager_thread_bos + THREAD_MANAGER_STACK_SIZE;
  /* Setup pipe to communicate with thread manager */
  if (__libc_pipe(manager_pipe) == -1) {
    free(__pthread_manager_thread_bos);
    return -1;
  }
  /* Start the thread manager */
  pid = 0;
  if (__builtin_expect (__pthread_initial_thread.p_report_events, 0))
    {
      /* It's a bit more complicated.  We have to report the creation of
	 the manager thread.  */
      int idx = __td_eventword (TD_CREATE);
      uint32_t mask = __td_eventmask (TD_CREATE);

      if ((mask & (__pthread_threads_events.event_bits[idx]
		   | __pthread_initial_thread.p_eventbuf.eventmask.event_bits[idx]))
	  != 0)
	{
	  __pthread_lock(__pthread_manager_thread.p_lock, NULL);

#ifdef NEED_SEPARATE_REGISTER_STACK
	  pid = __clone2(__pthread_manager_event,
			 (void **) __pthread_manager_thread_bos,
			 THREAD_MANAGER_STACK_SIZE,
			 CLONE_VM | CLONE_FS | CLONE_FILES | CLONE_SIGHAND,
			 (void *)(long)manager_pipe[0]);
#elif _STACK_GROWS_UP
	  pid = __clone(__pthread_manager_event,
			(void **) __pthread_manager_thread_bos,
			CLONE_VM | CLONE_FS | CLONE_FILES | CLONE_SIGHAND,
			(void *)(long)manager_pipe[0]);
#else
	  pid = __clone(__pthread_manager_event,
			(void **) __pthread_manager_thread_tos,
			CLONE_VM | CLONE_FS | CLONE_FILES | CLONE_SIGHAND,
			(void *)(long)manager_pipe[0]);
#endif

	  if (pid != -1)
	    {
	      /* Now fill in the information about the new thread in
	         the newly created thread's data structure.  We cannot let
	         the new thread do this since we don't know whether it was
	         already scheduled when we send the event.  */
	      __pthread_manager_thread.p_eventbuf.eventdata =
		&__pthread_manager_thread;
	      __pthread_manager_thread.p_eventbuf.eventnum = TD_CREATE;
	      __pthread_last_event = &__pthread_manager_thread;
	      __pthread_manager_thread.p_tid = 2* PTHREAD_THREADS_MAX + 1;
	      __pthread_manager_thread.p_pid = pid;

	      /* Now call the function which signals the event.  */
	      __linuxthreads_create_event ();
	    }

	  /* Now restart the thread.  */
	  __pthread_unlock(__pthread_manager_thread.p_lock);
	}
    }

  if (__builtin_expect (pid, 0) == 0)
    {
#ifdef NEED_SEPARATE_REGISTER_STACK
      pid = __clone2(__pthread_manager, (void **) __pthread_manager_thread_bos,
		     THREAD_MANAGER_STACK_SIZE,
		     CLONE_VM | CLONE_FS | CLONE_FILES | CLONE_SIGHAND,
		     (void *)(long)manager_pipe[0]);
#elif _STACK_GROWS_UP
      pid = __clone(__pthread_manager, (void **) __pthread_manager_thread_bos,
		    CLONE_VM | CLONE_FS | CLONE_FILES | CLONE_SIGHAND,
		    (void *)(long)manager_pipe[0]);
#else
      pid = __clone(__pthread_manager, (void **) __pthread_manager_thread_tos,
		    CLONE_VM | CLONE_FS | CLONE_FILES | CLONE_SIGHAND,
		    (void *)(long)manager_pipe[0]);
#endif
    }
  if (__builtin_expect (pid, 0) == -1) {
    free(__pthread_manager_thread_bos);
    __libc_close(manager_pipe[0]);
    __libc_close(manager_pipe[1]);
    return -1;
  }
  __pthread_manager_request = manager_pipe[1]; /* writing end */
  __pthread_manager_reader = manager_pipe[0]; /* reading end */
  __pthread_manager_thread.p_tid = 2* PTHREAD_THREADS_MAX + 1;
  __pthread_manager_thread.p_pid = pid;
  /* Make gdb aware of new thread manager */
  if (__builtin_expect (__pthread_threads_debug, 0) && __pthread_sig_debug > 0)
    {
      raise(__pthread_sig_debug);
      /* We suspend ourself and gdb will wake us up when it is
	 ready to handle us. */
      __pthread_wait_for_restart_signal(thread_self());
    }
  /* Synchronize debugging of the thread manager */
  request.req_kind = REQ_DEBUG;
  TEMP_FAILURE_RETRY(__libc_write(__pthread_manager_request,
				  (char *) &request, sizeof(request)));
  return 0;
}
Exemple #8
0
int __pthread_initialize_manager(void)
{
    int manager_pipe[2];
    int pid;
    int report_events;
    struct pthread_request request;

    *__libc_multiple_threads_ptr = 1;

    /* If basic initialization not done yet (e.g. we're called from a
       constructor run before our constructor), do it now */
    if (__pthread_initial_thread_bos == NULL) pthread_initialize();
    /* Setup stack for thread manager */
    __pthread_manager_thread_bos = malloc(THREAD_MANAGER_STACK_SIZE);
    if (__pthread_manager_thread_bos == NULL) return -1;
    __pthread_manager_thread_tos =
        __pthread_manager_thread_bos + THREAD_MANAGER_STACK_SIZE;

    /* On non-MMU systems we make sure that the initial thread bounds don't overlap
     * with the manager stack frame */
    NOMMU_INITIAL_THREAD_BOUNDS(__pthread_manager_thread_tos,__pthread_manager_thread_bos);
    PDEBUG("manager stack: size=%d, bos=%p, tos=%p\n", THREAD_MANAGER_STACK_SIZE,
           __pthread_manager_thread_bos, __pthread_manager_thread_tos);
#if 0
    PDEBUG("initial stack: estimate bos=%p, tos=%p\n",
           __pthread_initial_thread_bos, __pthread_initial_thread_tos);
#endif

    /* Setup pipe to communicate with thread manager */
    if (pipe(manager_pipe) == -1) {
        free(__pthread_manager_thread_bos);
        return -1;
    }
    /* Start the thread manager */
    pid = 0;
#ifdef USE_TLS
    if (__linuxthreads_initial_report_events != 0)
        THREAD_SETMEM (((pthread_descr) NULL), p_report_events,
                       __linuxthreads_initial_report_events);
    report_events = THREAD_GETMEM (((pthread_descr) NULL), p_report_events);
#else
    if (__linuxthreads_initial_report_events != 0)
        __pthread_initial_thread.p_report_events
            = __linuxthreads_initial_report_events;
    report_events = __pthread_initial_thread.p_report_events;
#endif
    if (__builtin_expect (report_events, 0))
    {
        /* It's a bit more complicated.  We have to report the creation of
        the manager thread.  */
        int idx = __td_eventword (TD_CREATE);
        uint32_t mask = __td_eventmask (TD_CREATE);

        if ((mask & (__pthread_threads_events.event_bits[idx]
                     | __pthread_initial_thread.p_eventbuf.eventmask.event_bits[idx]))
                != 0)
        {

            __pthread_lock(__pthread_manager_thread.p_lock, NULL);

#ifdef __ia64__
            pid = __clone2(__pthread_manager_event,
                           (void **) __pthread_manager_thread_tos,
                           THREAD_MANAGER_STACK_SIZE,
                           CLONE_VM | CLONE_FS | CLONE_FILES | CLONE_SIGHAND,
                           (void *)(long)manager_pipe[0]);
#else
            pid = clone(__pthread_manager_event,
                        (void **) __pthread_manager_thread_tos,
                        CLONE_VM | CLONE_FS | CLONE_FILES | CLONE_SIGHAND,
                        (void *)(long)manager_pipe[0]);
#endif

            if (pid != -1)
            {
                /* Now fill in the information about the new thread in
                   the newly created thread's data structure.  We cannot let
                   the new thread do this since we don't know whether it was
                   already scheduled when we send the event.  */
                __pthread_manager_thread.p_eventbuf.eventdata =
                    &__pthread_manager_thread;
                __pthread_manager_thread.p_eventbuf.eventnum = TD_CREATE;
                __pthread_last_event = &__pthread_manager_thread;
                __pthread_manager_thread.p_tid = 2* PTHREAD_THREADS_MAX + 1;
                __pthread_manager_thread.p_pid = pid;

                /* Now call the function which signals the event.  */
                __linuxthreads_create_event ();
            }
            /* Now restart the thread.  */
            __pthread_unlock(__pthread_manager_thread.p_lock);
        }
    }

    if (pid == 0) {
#ifdef __ia64__
        pid = __clone2(__pthread_manager, (void **) __pthread_manager_thread_tos,
                       THREAD_MANAGER_STACK_SIZE,
                       CLONE_VM | CLONE_FS | CLONE_FILES | CLONE_SIGHAND,
                       (void *)(long)manager_pipe[0]);
#else
        pid = clone(__pthread_manager, (void **) __pthread_manager_thread_tos,
                    CLONE_VM | CLONE_FS | CLONE_FILES | CLONE_SIGHAND,
                    (void *)(long)manager_pipe[0]);
#endif
    }
    if (pid == -1) {
        free(__pthread_manager_thread_bos);
        __libc_close(manager_pipe[0]);
        __libc_close(manager_pipe[1]);
        return -1;
    }
    __pthread_manager_request = manager_pipe[1]; /* writing end */
    __pthread_manager_reader = manager_pipe[0]; /* reading end */
    __pthread_manager_thread.p_tid = 2* PTHREAD_THREADS_MAX + 1;
    __pthread_manager_thread.p_pid = pid;

    /* Make gdb aware of new thread manager */
    if (__pthread_threads_debug && __pthread_sig_debug > 0)
    {
        raise(__pthread_sig_debug);
        /* We suspend ourself and gdb will wake us up when it is
        ready to handle us. */
        __pthread_wait_for_restart_signal(thread_self());
    }
    /* Synchronize debugging of the thread manager */
    PDEBUG("send REQ_DEBUG to manager thread\n");
    request.req_kind = REQ_DEBUG;
    TEMP_FAILURE_RETRY(__libc_write(__pthread_manager_request,
                                    (char *) &request, sizeof(request)));
    return 0;
}
Exemple #9
0
void __libc_vsyslog(int priority, const char *format, va_list arg_ptr)
{
  char buffer[BUF_SIZE];
  char time_buf[20];
  int buflen, headerlen;
  time_t now;
  struct tm now_tm;
  pid_t pid;
  int fd;
  int sigpipe;
  struct sigaction action, oldaction;
  int saved_errno = errno;

  /* check for invalid priority/facility bits */
  if (priority & ~(LOG_PRIMASK|LOG_FACMASK)) {
    syslog(LOG_ERR|LOG_CONS|LOG_PERROR|LOG_PID, "syslog: unknown facility/priorityority: %x", priority);
    priority &= LOG_PRIMASK|LOG_FACMASK;
  }

  /* check priority against setlogmask */
  if ((LOG_MASK(LOG_PRI(priority)) && LogMask) == 0) return;

  /* Set default facility if none specified. */
  if ((priority & LOG_FACMASK) == 0) priority |= LogFacility;

  pid = getpid();
  time(&now);
  strftime(time_buf, 20, "%h %e %T", localtime_r (&now, &now_tm));

  if (LogStat & LOG_PID)
    headerlen = snprintf(buffer, 130, "<%d>%s %s[%ld]: ", priority, time_buf, LogTag, (long) pid);
  else
    headerlen = snprintf(buffer, 130, "<%d>%s %s: ", priority, time_buf, LogTag);

  if (!LogTag[0]) {
    if ((LogStat & LOG_PID) != LOG_PID)
      headerlen = snprintf(buffer, 130, "<%d>%s (unknown)[%ld]: ", priority, time_buf, (long) pid);
    strcat(buffer+headerlen, "syslog without openlog w/ ident, please check code!");
    buflen = 41;
  }
  else {
    errno=saved_errno;
    buflen = vsnprintf(buffer+headerlen, BUF_SIZE - headerlen, format, arg_ptr);
  }
  if (LogStat & LOG_PERROR) {
    __libc_write(1, buffer+headerlen, buflen);
    if (buffer[headerlen+buflen] != '\n') __libc_write(1,"\n", 1);
  }

  /* prepare for broken connection */
  memset(&action, 0, sizeof(action));
  action.sa_handler = SIG_IGN;
  sigemptyset(&action.sa_mask);

  sigpipe = sigaction (SIGPIPE, &action, &oldaction);

  if (!connected) openlog_intern(LogStat | LOG_NDELAY, 0);

  /* If we have a SOCK_STREAM connection, also send ASCII NUL as a
   * record terminator. */
  if (LogType == SOCK_STREAM) buflen++;

  if (!connected || (send(LogFile, buffer, buflen+headerlen, 0) != buflen+headerlen)) {
    if (LogType == SOCK_STREAM) buflen--;
    closelog_intern();
    /*
     * Output the message to the console; don't worry about blocking,
     * if console blocks everything will.  Make sure the error reported
     * is the one from the syslogd failure.
     */
    if ((LogStat & LOG_CONS) &&
       ((fd = __libc_open(_PATH_CONSOLE, O_WRONLY|O_NOCTTY, 0)) >= 0))
    {
      __libc_write(fd, buffer, buflen+headerlen);
      __libc_write(fd, "\r\n", 2);
      __libc_close(fd);
    }
  }

  if (sigpipe == 0)
    sigaction(SIGPIPE, &oldaction, (struct sigaction *) NULL);
}