Package: libgnustep-base1.25
Version: 1.25.0-2

The privateSetLocale() function can use memory that has been already freed:

  $ make -s test-locale OBJCFLAGS="$(gnustep-config --objc-flags) $(gnustep-config 
--base-libs)"
  test-locale.m: In function ‘main’:
  test-locale.m:10:18: warning: unused variable ‘defs’ [-Wunused-variable]
    NSUserDefaults *defs = [NSUserDefaults standardUserDefaults];
                    ^~~~

  $ valgrind -q -- ./test-locale
  ==9722== Invalid read of size 1
  ==9722==    at 0x48313D8: strlen (in 
/usr/lib/valgrind/vgpreload_memcheck-x86-linux.so)
  ==9722==    by 0x4A5FD89: _i_NSString__initWithCString_encoding_ 
(NSString.m:1246)
  ==9722==    by 0x4A5CAB3: _c_NSString__stringWithCString_encoding_ 
(NSString.m:954)
  ==9722==    by 0x48E2897: privateSetLocale (GSLocale.m:75)
  ==9722==    by 0x48E37CB: GSDefaultLanguageLocale (GSLocale.m:330)
  ==9722==    by 0x4A9BFCC: systemLanguages (NSUserDefaults.m:375)
  ==9722==    by 0x4A9BFCC: newLanguages (NSUserDefaults.m:397)
  ==9722==    by 0x4A9DF6D: _c_NSUserDefaults__standardUserDefaults 
(NSUserDefaults.m:928)
  ==9722==    by 0x10878E: main (test-locale.m:10)
  ==9722==  Address 0x7a78688 is 0 bytes inside a block of size 181 free'd
  ==9722==    at 0x482F478: free (in 
/usr/lib/valgrind/vgpreload_memcheck-x86-linux.so)
  ==9722==    by 0x4E9CE77: setname (setlocale.c:201)
  ==9722==    by 0x4E9CE77: setlocale (setlocale.c:456)
  ==9722==    by 0x4B0D13D: GSPrivateNativeCStringEncoding (Unicode.m:2862)
  ==9722==    by 0x48E2891: privateSetLocale (GSLocale.m:75)
  ==9722==    by 0x48E37CB: GSDefaultLanguageLocale (GSLocale.m:330)
  ==9722==    by 0x4A9BFCC: systemLanguages (NSUserDefaults.m:375)
  ==9722==    by 0x4A9BFCC: newLanguages (NSUserDefaults.m:397)
  ==9722==    by 0x4A9DF6D: _c_NSUserDefaults__standardUserDefaults 
(NSUserDefaults.m:928)
  ==9722==    by 0x10878E: main (test-locale.m:10)
  ==9722==  Block was alloc'd at
  ==9722==    at 0x482E2BC: malloc (in 
/usr/lib/valgrind/vgpreload_memcheck-x86-linux.so)
  ==9722==    by 0x4E9C998: new_composite_name (setlocale.c:172)
  ==9722==    by 0x4E9CF49: setlocale (setlocale.c:378)
  ==9722==    by 0x108742: main (test-locale.m:8)
  ...

This happens because it calls setlocale twice; once directly:

 clocale = setlocale(category, clocale);

and then again indirectly: ToString -> GSPrivateNativeCStringEncoding -> setlocale.

The other call invalidates the clocale pointer, as allowed by POSIX: "The returned string pointer might be invalidated or the string content might be overwritten by a subsequent call to setlocale()."


-- System Information:
Architecture: i386

Versions of packages libgnustep-base1.25 depends on:
ii  gnustep-base-common  1.25.0-2
ii  libavahi-client3     0.7-3
ii  libavahi-common3     0.7-3
ii  libc6                2.24-17
ii  libffi6              3.2.1-6
ii  libgcc1              1:7.2.0-12
ii  libgnutls30          3.5.16-1
ii  libicu57             57.1-8
ii  libobjc4             7.2.0-12
ii  libxml2              2.9.4+dfsg1-5
ii  libxslt1.1           1.1.29-2.2
ii  zlib1g               1:1.2.8.dfsg-5

Versions of packages libgnustep-base1.25 recommends:
ii  gnustep-base-runtime  1.25.0-2

--
Jakub Wilk
#include <locale.h>

#import <Foundation/NSAutoreleasePool.h>
#import <Foundation/NSUserDefaults.h>

int main()
{
        setlocale(LC_ALL, "");
        NSAutoreleasePool *arp = [NSAutoreleasePool new];
        NSUserDefaults *defs = [NSUserDefaults standardUserDefaults];
        [arp release];
        return 0;
}

Reply via email to