delorie.com/archives/browse.cgi   search  
Mail Archives: cygwin-developers/1999/05/04/13:37:03

Mailing-List: contact cygwin-developers-help AT sourceware DOT cygnus DOT com; run by ezmlm
Sender: cygwin-developers-owner AT sourceware DOT cygnus DOT com
Delivered-To: mailing list cygwin-developers AT sourceware DOT cygnus DOT com
Message-ID: <372F2F7F.2DDE07F3@hem2.passagen.se>
Date: Tue, 04 May 1999 19:33:51 +0200
From: Anders Norlander <anorland AT hem2 DOT passagen DOT se>
X-Mailer: Mozilla 4.01 [en] (Win95; I)
MIME-Version: 1.0
To: cygwin devel <cygwin-developers AT sourceware DOT cygnus DOT com>
CC: Corinna Vinschen <corinna DOT vinschen AT cityweb DOT de>,
Chris Faylor <cgf AT cygnus DOT com>
Subject: Re: Patch, Version 4: Problem solved
X-Priority: 3 (Normal)

Corinna Vinschen wrote:
[snip]
>The sizes and offsets of the structures TOKEN_PRIVILEGES and
>LUID_AND_ATTRIBUTES are different between the old and the new defines:
[snip]

>new:
>====
>typedef struct _LUID_AND_ATTRIBUTES {
>        LUID   Luid;                           offset 0, size 8
>        DWORD  Attributes;                     offset 8, size 4
>} LUID_AND_ATTRIBUTES;                                   size 16!!!
>
[snip]

>This happens, because of the new definition of LARGE_INTEGER, which is
>the base type for LUID. It now contains a union member of type
>LONGLONG (8 Bytes):
[snip]
>So gcc alignes the LUID type to a 8 byte boundary, instead of a
>4 byte boundary.
>For testing purposes, I have made the "LONGLONG QuadPart" to a comment
>and now, AdjustTokenPrivileges() works as expected.

I investigated this and come up with a minimal testcase and sent
it to egcs-bugs. I've attached the bug report below.

>So I like to suggest, to erase the definition of QuadPart in the
>definitions of LARGE_INTEGER and ULARGE_INTEGER in include/winnt.h,
>until the alignment problem is solved. The fix is following.
>Moreover, I have attached a tiny fix to my security patch, which
>solves a "permission denied" problem, if you set file permissions
>to e.g. "chmod 000 foo".
It is also possible to solve by using the packed attribute. Perhaps
that is better?

Report sent to egcs-bugs:
Consider the code below (on egcs 1.1.1 ix86 platforms):
<code>
#include <stdio.h>

/* get member offset */
#define ofs(t,f) ((int)&(((t*)0)->f))

typedef struct {
        int a;
        int b;
} A;

typedef struct {
  A a;
  int i;
} B;

int main()
{
  B b;
  printf("B: %d\n.a: %d, %d\n.i: %d, %d\n", sizeof(B),
         sizeof(b.a), ofs(B,a),
         sizeof(b.i), ofs(B,i));
  return 0;
}
</code>

When running the compiled program you get
B: 12
.a: 8, 0
.i: 4, 8

Now change the defintion of A to
typedef struct {
        double d; /* or long long */
} A;

now you get
B: 16  <-- why?
.u: 8, 0
.i: 4, 8

For some subtle reason egcs aligns B on a 16 byte
boundary, the alignment of A is not changed but the alignment
of B which has a member of type A. This, however, only happens
when you put an eight bytes large numeric type in A. So even no
sizes have changed, alignment has.
Is this a (mis)feature or perhaps an off-by-one error in egcs?
Using gcc 2.7.3 you get the expected results.

Regards,
Anders

- Raw text -


  webmaster     delorie software   privacy  
  Copyright © 2019   by DJ Delorie     Updated Jul 2019