Follow @Openwall on Twitter for new release announcements and other news
[<prev] [next>] [<thread-prev] [day] [month] [year] [list]
Message-ID: <20110522160914.GR277@brightrain.aerifal.cx>
Date: Sun, 22 May 2011 12:09:14 -0400
From: Rich Felker <dalias@...ifal.cx>
To: musl@...ts.openwall.com
Subject: Re: linux/sbrk is wrong

On Sun, May 22, 2011 at 04:55:55PM +0200, Szabolcs Nagy wrote:
> linux brk syscall returns the end pointer
> so if it fails then the old one
> if it succeeds then the new one
> 
> the current implementation of sbrk returns
> the end of the allocated area instead of
> the begining

IMO there's no way for correct code to use these functions anyway, but
I'll fix them anyway.

>  int brk(void *end)
>  {
> -	return -(syscall(SYS_brk, end) == -1);
> +	return -((void *)syscall(SYS_brk, end) != end);
>  }

This looks fine.

>  void *sbrk(ptrdiff_t inc)
>  {
> -	return (void *)syscall(SYS_brk, syscall(SYS_brk, 0)+inc);
> +	void *p = (void *)syscall(SYS_brk, 0);
> +
> +	if (inc == 0)
> +		return p;
> +	if ((void *)syscall(SYS_brk, p+inc) == p+inc)

This line is invalid C. p+inc is not defined since p has type void *.
The most correct would probably be to use uintptr_t internally
everywhere and just cast to void * in the return statement.

Rich

Powered by blists - more mailing lists

Confused about mailing lists and their use? Read about mailing lists on Wikipedia and check out these guidelines on proper formatting of your messages.