PHPFixing
  • Privacy Policy
  • TOS
  • Ask Question
  • Contact Us
  • Home
  • PHP
  • Programming
  • SQL Injection
  • Web3.0

Tuesday, July 19, 2022

[FIXED] Why final pointer is being aligned to size of int?

 July 19, 2022     c, integer, pointers     No comments   

Issue

Here's the code under consideration:

#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>

char buffer[512];
int pos;
int posf;
int i;
struct timeval *tv;

int main(int argc, char **argv)
{
    pos = 0;
    for (i = 0; i < 512; i++) buffer[i] = 0;
    for (i = 0; i < 4; i++)
    {
        printf("pos = %d\n", pos);
        *(int *)(buffer + pos + 4) = 0x12345678;
        pos += 9;
    }

    for (i = 0; i < 9 * 4; i++)
    {
        printf(" %02X", (int)(unsigned char)*(buffer + i));
        if ((i % 9) == 8) printf("\n");
    }
    printf("\n");

    // ---  

    pos = 0;
    for (i = 0; i < 512; i++) buffer[i] = 0;
    *(int *)(buffer + 4) = 0x12345678;
    *(int *)(buffer + 9 + 4) = 0x12345678;
    *(int *)(buffer + 18 + 4) = 0x12345678;
    *(int *)(buffer + 27 + 4) = 0x12345678;

    for (i = 0; i < 9 * 4; i++)
    {
        printf(" %02X", (int)(unsigned char)*(buffer + i));
        if ((i % 9) == 8) printf("\n");
    }
    printf("\n");

    return 0;
}

And the output of code is

pos = 0
pos = 9
pos = 18
pos = 27
 00 00 00 00 78 56 34 12 00
 00 00 00 78 56 34 12 00 00
 00 00 78 56 34 12 00 00 00
 00 78 56 34 12 00 00 00 00

 00 00 00 00 78 56 34 12 00
 00 00 00 00 78 56 34 12 00
 00 00 00 00 78 56 34 12 00
 00 00 00 00 78 56 34 12 00

I can not get why

*(int *)(buffer + pos + 4) = 0x12345678;

is being placed into the address aligned to size of int (4 bytes). I expect the following actions during the execution of this command:

  1. pointer to buffer, which is char*, increased by the value of pos (0, 9, 18, 27) and then increased by 4. The resulting pointer is char* pointing to char array index [pos + 4];
  2. char* pointer in the brackets is being converted to the int*, causing resulting pointer addressing integer of 4 bytes size at base location (buffer + pos + 4) and integer array index [0];
  3. resulting int* location is being stored with bytes 78 56 34 12 in this order (little endian system).

Instead I see pointer in brackets being aligned to size of int (4 bytes), however direct addressing using constants (see second piece of code) works properly as expected.

  • target CPU is i.MX287 (ARM9);
  • target operating system is OpenWrt Linux [...] 3.18.29 #431 Fri Feb 11 15:57:31 2022 armv5tejl GNU/Linux;
  • compiled on Linux [...] 4.15.0-142-generic #146~16.04.1-Ubuntu SMP Tue Apr 13 09:27:15 UTC 2021 x86_64 x86_64 x86_64 GNU/Linux, installed in Virtual machine;
  • GCC compiler version gcc (Ubuntu 5.4.0-6ubuntu1~16.04.12) 5.4.0 20160609
  • I compile as a part of whole system image compilation, flags are CFLAGS = -Os -Wall -Wmissing-declarations -g3.

Update: thanks to Andrew Henle, I now replace

*(int*)(buffer + pos + 4) = 0x12345678;

with

        buffer[pos + 4] = value & 0xff;
        buffer[pos + 5] = (value >> 8) & 0xff;
        buffer[pos + 6] = (value >> 16) & 0xff;
        buffer[pos + 7] = (value >> 24) & 0xff;

and can't believe I must do it on 32-bit microprocessor system, whatever architecture it has, and that GCC is not able to properly slice int into bytes or partial int words and perform RMW for those parts.


Solution

char* pointer in the brackets is being converted to the int*, causing resulting pointer addressing integer of 4 bytes size at base location (buffer + pos + 4) and integer array index [0]

This incurs undefined behavior (UB) when the alignments requirements of int * are not met.

Instead copy with memcpy(). A good compiler will emit valid optimized code.

// *(int*)(buffer + pos + 4) = 0x12345678;
memcpy(buffer + pos + 4, &(int){0x12345678}, sizeof (int));


Answered By - chux - Reinstate Monica
Answer Checked By - David Marino (PHPFixing Volunteer)
  • Share This:  
  •  Facebook
  •  Twitter
  •  Stumble
  •  Digg
Newer Post Older Post Home

0 Comments:

Post a Comment

Note: Only a member of this blog may post a comment.

Total Pageviews

Featured Post

Why Learn PHP Programming

Why Learn PHP Programming A widely-used open source scripting language PHP is one of the most popular programming languages in the world. It...

Subscribe To

Posts
Atom
Posts
Comments
Atom
Comments

Copyright © PHPFixing