Openwall GNU/*/Linux - a small security-enhanced Linux distro for servers
[<prev] [next>] [day] [month] [year] [list]
Date: Sat, 12 Aug 2017 00:38:53 -0500
From: Bobby Bingham <koorogi@...rogi.info>
To: musl@...ts.openwall.com
Subject: pthread_setattr_default_np behavior difference from glibc

I've got a glibc-linked binary I'm trying to get running, and I'm
running into the usual stack overflow for threads other than the main
thread because of musl's smaller default stack size.  So I decided to
see if I could LD_PRELOAD a library with a constructor that used
pthread_setattr_default_np to increase the default stack size.

It turns out that it doesn't work for this binary because it passes a
thread attribute object to pthread_create without explicitly setting the
stack size in the attribute object.  According to the man page, the
values set with pthread_getattr_default_np are only used if no attribute
object is passed to pthread_create, which is how musl behaves.

It turns out this isn't what glibc does for stack size (but is for guard
size).

glibc's pthread_attr_init sets the stack size field in the attribute
object to zero, which is interpreted to mean the default stack size at
whatever time it's queried.  The attached program will print two
different stack sizes on glibc.

I think that the glibc behavior is problematic because
pthread_attr_getstacksize can return a value different than what will
actually be used if the default is changed before pthread_create is
called.

However, if we changed pthread_attr_init to initialize the stack size
based on the current default at the time its called, we'd be a little
closer to glibc's behavior, but without the quirk I mentioned above.
And it would fix my use case :)

Thoughts?

--
Bobby

#define _GNU_SOURCE
#include <pthread.h>
#include <stdio.h>

static void print_stacksize(char *label, pthread_attr_t *a)
{
	size_t s;
	pthread_attr_getstacksize(a, &s);
	printf("%s: %zu\n", label, s);
}

int main()
{
	pthread_attr_t a, def;

	pthread_attr_init(&a);
	print_stacksize("original stack size", &a);

	pthread_attr_init(&def);
	pthread_attr_setstacksize(&def, 1234567890);
	pthread_setattr_default_np(&def);

	print_stacksize("stack size after changing default", &a);
	return 0;
}

Powered by blists - more mailing lists

Your e-mail address:

Powered by Openwall GNU/*/Linux - Powered by OpenVZ