Can the code of some C++ class accidentally overwrite a private static variable of another class?





.everyoneloves__top-leaderboard:empty,.everyoneloves__mid-leaderboard:empty,.everyoneloves__bot-mid-leaderboard:empty{ height:90px;width:728px;box-sizing:border-box;
}







0















I mean a scenario like this: There is some class (I call it victim) with a private data member and another class (named attacker) with some method, which, of course, normally does not have access to private members of other classes and does not even hold a reference to an instance of victim:



extern "C" {
#include <pigpiod_if2.h>
}

class victim {
private:
static bool is_ready;
static bool is_on;
public:
static void init ()
{
is_ready = true;
is_on = true;
}

/* Some other public methods go here. */
}

class attacker {
private:
static int last_read_pin;
public:
static void run ()
{
while (true) {
/* Some sensible code goes here. */
last_read_pin = -1;
time_sleep (0.01); // Using nanosleep () does not change behavior.
}
}
}


This is just a code snippet to illustrate the following question: Is it possible, not just in theory, but also practically, that attacker::run () can modify the values of the two private static vars of victim unintentionally, without addressing any public member of victim, maybe due to undefined behavior or even a compiler bug? Thank you.



UPDATE: After a hint from another user, I did rebuild the complete app using make clean and make. Also, I added the endless loop into my example. The change in is_ready occurs during the sixth run of the loop. Changing the sleep interval does not change behavior, though.



UPDATE #2: I ran my code through gdb with a watch on the is_ready variable, and I got an alert when last_read_pin was set to –1:



Hardware watchpoint 1: is_ready

Old value = true
New value = false
attacker::Run ()
last_read_pin = -1;


UPDATE #3: Moving last_read_pin into the Run () method itself, thereby making it an internal variable, does not help either.



UPDATE #4: After simply commenting out the line of code, which makes so much trouble, the issue still persisten, apparently being caused by one line above, which reads like this:



keypad::last_levels [h] [k] = 0;



I had to comment out this line, too, to get rid of the problem with is_ready being changed.



Could the use of pigpiod cause this issue? I an earlier version, I was using pigpio directly and did not encounter this problem.



Compiled with gcc 4.9.2.










share|improve this question




















  • 6





    Yes, anything is possible with undefined behavior.

    – melpomene
    Nov 16 '18 at 23:11











  • I am pretty sure you can abuse the language to do this on purpose (aka it's very obvious when you do it), I don't exactly recall how though. Maybe you are reading uninitialized memory (likely), corrupting the object memory (less likely) or encountering just another sort of weirdness in your real usecase - assuming your question is related to a real problem in a larger codebase.

    – Asu
    Nov 16 '18 at 23:13






  • 5





    The private mechanism in C++ isn't a security system, and can be pretty trivially be got around. However, it's unlikely (though not impossible) that you can modify private member variables unintentionally.

    – Neil Butterworth
    Nov 16 '18 at 23:19








  • 2





    Easy to do with a versioning problem. Old non-recompiled code uses a new class that is bigger.

    – Hans Passant
    Nov 17 '18 at 0:31






  • 3





    If code like this leads to behaviour like you describe, you are most likely dealing with either a compiler bug or a hardware bug. Though one cannot exclude UB that occurs elsewhere weirdly interacting with this code. Another pissibility is gdb misidentifying the offending line. It is really hard to tell without seeing the whole picture.

    – n.m.
    Nov 18 '18 at 16:45


















0















I mean a scenario like this: There is some class (I call it victim) with a private data member and another class (named attacker) with some method, which, of course, normally does not have access to private members of other classes and does not even hold a reference to an instance of victim:



extern "C" {
#include <pigpiod_if2.h>
}

class victim {
private:
static bool is_ready;
static bool is_on;
public:
static void init ()
{
is_ready = true;
is_on = true;
}

/* Some other public methods go here. */
}

class attacker {
private:
static int last_read_pin;
public:
static void run ()
{
while (true) {
/* Some sensible code goes here. */
last_read_pin = -1;
time_sleep (0.01); // Using nanosleep () does not change behavior.
}
}
}


This is just a code snippet to illustrate the following question: Is it possible, not just in theory, but also practically, that attacker::run () can modify the values of the two private static vars of victim unintentionally, without addressing any public member of victim, maybe due to undefined behavior or even a compiler bug? Thank you.



UPDATE: After a hint from another user, I did rebuild the complete app using make clean and make. Also, I added the endless loop into my example. The change in is_ready occurs during the sixth run of the loop. Changing the sleep interval does not change behavior, though.



UPDATE #2: I ran my code through gdb with a watch on the is_ready variable, and I got an alert when last_read_pin was set to –1:



Hardware watchpoint 1: is_ready

Old value = true
New value = false
attacker::Run ()
last_read_pin = -1;


UPDATE #3: Moving last_read_pin into the Run () method itself, thereby making it an internal variable, does not help either.



UPDATE #4: After simply commenting out the line of code, which makes so much trouble, the issue still persisten, apparently being caused by one line above, which reads like this:



keypad::last_levels [h] [k] = 0;



I had to comment out this line, too, to get rid of the problem with is_ready being changed.



Could the use of pigpiod cause this issue? I an earlier version, I was using pigpio directly and did not encounter this problem.



Compiled with gcc 4.9.2.










share|improve this question




















  • 6





    Yes, anything is possible with undefined behavior.

    – melpomene
    Nov 16 '18 at 23:11











  • I am pretty sure you can abuse the language to do this on purpose (aka it's very obvious when you do it), I don't exactly recall how though. Maybe you are reading uninitialized memory (likely), corrupting the object memory (less likely) or encountering just another sort of weirdness in your real usecase - assuming your question is related to a real problem in a larger codebase.

    – Asu
    Nov 16 '18 at 23:13






  • 5





    The private mechanism in C++ isn't a security system, and can be pretty trivially be got around. However, it's unlikely (though not impossible) that you can modify private member variables unintentionally.

    – Neil Butterworth
    Nov 16 '18 at 23:19








  • 2





    Easy to do with a versioning problem. Old non-recompiled code uses a new class that is bigger.

    – Hans Passant
    Nov 17 '18 at 0:31






  • 3





    If code like this leads to behaviour like you describe, you are most likely dealing with either a compiler bug or a hardware bug. Though one cannot exclude UB that occurs elsewhere weirdly interacting with this code. Another pissibility is gdb misidentifying the offending line. It is really hard to tell without seeing the whole picture.

    – n.m.
    Nov 18 '18 at 16:45














0












0








0








I mean a scenario like this: There is some class (I call it victim) with a private data member and another class (named attacker) with some method, which, of course, normally does not have access to private members of other classes and does not even hold a reference to an instance of victim:



extern "C" {
#include <pigpiod_if2.h>
}

class victim {
private:
static bool is_ready;
static bool is_on;
public:
static void init ()
{
is_ready = true;
is_on = true;
}

/* Some other public methods go here. */
}

class attacker {
private:
static int last_read_pin;
public:
static void run ()
{
while (true) {
/* Some sensible code goes here. */
last_read_pin = -1;
time_sleep (0.01); // Using nanosleep () does not change behavior.
}
}
}


This is just a code snippet to illustrate the following question: Is it possible, not just in theory, but also practically, that attacker::run () can modify the values of the two private static vars of victim unintentionally, without addressing any public member of victim, maybe due to undefined behavior or even a compiler bug? Thank you.



UPDATE: After a hint from another user, I did rebuild the complete app using make clean and make. Also, I added the endless loop into my example. The change in is_ready occurs during the sixth run of the loop. Changing the sleep interval does not change behavior, though.



UPDATE #2: I ran my code through gdb with a watch on the is_ready variable, and I got an alert when last_read_pin was set to –1:



Hardware watchpoint 1: is_ready

Old value = true
New value = false
attacker::Run ()
last_read_pin = -1;


UPDATE #3: Moving last_read_pin into the Run () method itself, thereby making it an internal variable, does not help either.



UPDATE #4: After simply commenting out the line of code, which makes so much trouble, the issue still persisten, apparently being caused by one line above, which reads like this:



keypad::last_levels [h] [k] = 0;



I had to comment out this line, too, to get rid of the problem with is_ready being changed.



Could the use of pigpiod cause this issue? I an earlier version, I was using pigpio directly and did not encounter this problem.



Compiled with gcc 4.9.2.










share|improve this question
















I mean a scenario like this: There is some class (I call it victim) with a private data member and another class (named attacker) with some method, which, of course, normally does not have access to private members of other classes and does not even hold a reference to an instance of victim:



extern "C" {
#include <pigpiod_if2.h>
}

class victim {
private:
static bool is_ready;
static bool is_on;
public:
static void init ()
{
is_ready = true;
is_on = true;
}

/* Some other public methods go here. */
}

class attacker {
private:
static int last_read_pin;
public:
static void run ()
{
while (true) {
/* Some sensible code goes here. */
last_read_pin = -1;
time_sleep (0.01); // Using nanosleep () does not change behavior.
}
}
}


This is just a code snippet to illustrate the following question: Is it possible, not just in theory, but also practically, that attacker::run () can modify the values of the two private static vars of victim unintentionally, without addressing any public member of victim, maybe due to undefined behavior or even a compiler bug? Thank you.



UPDATE: After a hint from another user, I did rebuild the complete app using make clean and make. Also, I added the endless loop into my example. The change in is_ready occurs during the sixth run of the loop. Changing the sleep interval does not change behavior, though.



UPDATE #2: I ran my code through gdb with a watch on the is_ready variable, and I got an alert when last_read_pin was set to –1:



Hardware watchpoint 1: is_ready

Old value = true
New value = false
attacker::Run ()
last_read_pin = -1;


UPDATE #3: Moving last_read_pin into the Run () method itself, thereby making it an internal variable, does not help either.



UPDATE #4: After simply commenting out the line of code, which makes so much trouble, the issue still persisten, apparently being caused by one line above, which reads like this:



keypad::last_levels [h] [k] = 0;



I had to comment out this line, too, to get rid of the problem with is_ready being changed.



Could the use of pigpiod cause this issue? I an earlier version, I was using pigpio directly and did not encounter this problem.



Compiled with gcc 4.9.2.







c++ undefined-behavior private-members






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited Nov 18 '18 at 23:28







Neppomuk

















asked Nov 16 '18 at 23:06









NeppomukNeppomuk

1731315




1731315








  • 6





    Yes, anything is possible with undefined behavior.

    – melpomene
    Nov 16 '18 at 23:11











  • I am pretty sure you can abuse the language to do this on purpose (aka it's very obvious when you do it), I don't exactly recall how though. Maybe you are reading uninitialized memory (likely), corrupting the object memory (less likely) or encountering just another sort of weirdness in your real usecase - assuming your question is related to a real problem in a larger codebase.

    – Asu
    Nov 16 '18 at 23:13






  • 5





    The private mechanism in C++ isn't a security system, and can be pretty trivially be got around. However, it's unlikely (though not impossible) that you can modify private member variables unintentionally.

    – Neil Butterworth
    Nov 16 '18 at 23:19








  • 2





    Easy to do with a versioning problem. Old non-recompiled code uses a new class that is bigger.

    – Hans Passant
    Nov 17 '18 at 0:31






  • 3





    If code like this leads to behaviour like you describe, you are most likely dealing with either a compiler bug or a hardware bug. Though one cannot exclude UB that occurs elsewhere weirdly interacting with this code. Another pissibility is gdb misidentifying the offending line. It is really hard to tell without seeing the whole picture.

    – n.m.
    Nov 18 '18 at 16:45














  • 6





    Yes, anything is possible with undefined behavior.

    – melpomene
    Nov 16 '18 at 23:11











  • I am pretty sure you can abuse the language to do this on purpose (aka it's very obvious when you do it), I don't exactly recall how though. Maybe you are reading uninitialized memory (likely), corrupting the object memory (less likely) or encountering just another sort of weirdness in your real usecase - assuming your question is related to a real problem in a larger codebase.

    – Asu
    Nov 16 '18 at 23:13






  • 5





    The private mechanism in C++ isn't a security system, and can be pretty trivially be got around. However, it's unlikely (though not impossible) that you can modify private member variables unintentionally.

    – Neil Butterworth
    Nov 16 '18 at 23:19








  • 2





    Easy to do with a versioning problem. Old non-recompiled code uses a new class that is bigger.

    – Hans Passant
    Nov 17 '18 at 0:31






  • 3





    If code like this leads to behaviour like you describe, you are most likely dealing with either a compiler bug or a hardware bug. Though one cannot exclude UB that occurs elsewhere weirdly interacting with this code. Another pissibility is gdb misidentifying the offending line. It is really hard to tell without seeing the whole picture.

    – n.m.
    Nov 18 '18 at 16:45








6




6





Yes, anything is possible with undefined behavior.

– melpomene
Nov 16 '18 at 23:11





Yes, anything is possible with undefined behavior.

– melpomene
Nov 16 '18 at 23:11













I am pretty sure you can abuse the language to do this on purpose (aka it's very obvious when you do it), I don't exactly recall how though. Maybe you are reading uninitialized memory (likely), corrupting the object memory (less likely) or encountering just another sort of weirdness in your real usecase - assuming your question is related to a real problem in a larger codebase.

– Asu
Nov 16 '18 at 23:13





I am pretty sure you can abuse the language to do this on purpose (aka it's very obvious when you do it), I don't exactly recall how though. Maybe you are reading uninitialized memory (likely), corrupting the object memory (less likely) or encountering just another sort of weirdness in your real usecase - assuming your question is related to a real problem in a larger codebase.

– Asu
Nov 16 '18 at 23:13




5




5





The private mechanism in C++ isn't a security system, and can be pretty trivially be got around. However, it's unlikely (though not impossible) that you can modify private member variables unintentionally.

– Neil Butterworth
Nov 16 '18 at 23:19







The private mechanism in C++ isn't a security system, and can be pretty trivially be got around. However, it's unlikely (though not impossible) that you can modify private member variables unintentionally.

– Neil Butterworth
Nov 16 '18 at 23:19






2




2





Easy to do with a versioning problem. Old non-recompiled code uses a new class that is bigger.

– Hans Passant
Nov 17 '18 at 0:31





Easy to do with a versioning problem. Old non-recompiled code uses a new class that is bigger.

– Hans Passant
Nov 17 '18 at 0:31




3




3





If code like this leads to behaviour like you describe, you are most likely dealing with either a compiler bug or a hardware bug. Though one cannot exclude UB that occurs elsewhere weirdly interacting with this code. Another pissibility is gdb misidentifying the offending line. It is really hard to tell without seeing the whole picture.

– n.m.
Nov 18 '18 at 16:45





If code like this leads to behaviour like you describe, you are most likely dealing with either a compiler bug or a hardware bug. Though one cannot exclude UB that occurs elsewhere weirdly interacting with this code. Another pissibility is gdb misidentifying the offending line. It is really hard to tell without seeing the whole picture.

– n.m.
Nov 18 '18 at 16:45












1 Answer
1






active

oldest

votes


















0














After floating around the code line in question, I found out that the blunder was lying in the line before, which reads as follows:



last_levels [h] [l] = 0;


Unfortunately, h can be < 0. In this case, some kinda exception (array index out of bounds) should be thrown, but unfortunately, it isn't (Does anybody know why?). The gdb gave me the wrong information of the overwrite of is_ready to happen in the following line (Is this maybe a bug?), and I believed this without any criticism. As if this wasn't enough, this error made no problems until I changed my code in a completely different place!



This blunder has cost me quite much time, but now, at last, I know what its cause was, and I corrected it successfully. Thank you anyway for your hints and comments!






share|improve this answer
























    Your Answer






    StackExchange.ifUsing("editor", function () {
    StackExchange.using("externalEditor", function () {
    StackExchange.using("snippets", function () {
    StackExchange.snippets.init();
    });
    });
    }, "code-snippets");

    StackExchange.ready(function() {
    var channelOptions = {
    tags: "".split(" "),
    id: "1"
    };
    initTagRenderer("".split(" "), "".split(" "), channelOptions);

    StackExchange.using("externalEditor", function() {
    // Have to fire editor after snippets, if snippets enabled
    if (StackExchange.settings.snippets.snippetsEnabled) {
    StackExchange.using("snippets", function() {
    createEditor();
    });
    }
    else {
    createEditor();
    }
    });

    function createEditor() {
    StackExchange.prepareEditor({
    heartbeatType: 'answer',
    autoActivateHeartbeat: false,
    convertImagesToLinks: true,
    noModals: true,
    showLowRepImageUploadWarning: true,
    reputationToPostImages: 10,
    bindNavPrevention: true,
    postfix: "",
    imageUploader: {
    brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
    contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
    allowUrls: true
    },
    onDemand: true,
    discardSelector: ".discard-answer"
    ,immediatelyShowMarkdownHelp:true
    });


    }
    });














    draft saved

    draft discarded


















    StackExchange.ready(
    function () {
    StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53346531%2fcan-the-code-of-some-c-class-accidentally-overwrite-a-private-static-variable%23new-answer', 'question_page');
    }
    );

    Post as a guest















    Required, but never shown

























    1 Answer
    1






    active

    oldest

    votes








    1 Answer
    1






    active

    oldest

    votes









    active

    oldest

    votes






    active

    oldest

    votes









    0














    After floating around the code line in question, I found out that the blunder was lying in the line before, which reads as follows:



    last_levels [h] [l] = 0;


    Unfortunately, h can be < 0. In this case, some kinda exception (array index out of bounds) should be thrown, but unfortunately, it isn't (Does anybody know why?). The gdb gave me the wrong information of the overwrite of is_ready to happen in the following line (Is this maybe a bug?), and I believed this without any criticism. As if this wasn't enough, this error made no problems until I changed my code in a completely different place!



    This blunder has cost me quite much time, but now, at last, I know what its cause was, and I corrected it successfully. Thank you anyway for your hints and comments!






    share|improve this answer




























      0














      After floating around the code line in question, I found out that the blunder was lying in the line before, which reads as follows:



      last_levels [h] [l] = 0;


      Unfortunately, h can be < 0. In this case, some kinda exception (array index out of bounds) should be thrown, but unfortunately, it isn't (Does anybody know why?). The gdb gave me the wrong information of the overwrite of is_ready to happen in the following line (Is this maybe a bug?), and I believed this without any criticism. As if this wasn't enough, this error made no problems until I changed my code in a completely different place!



      This blunder has cost me quite much time, but now, at last, I know what its cause was, and I corrected it successfully. Thank you anyway for your hints and comments!






      share|improve this answer


























        0












        0








        0







        After floating around the code line in question, I found out that the blunder was lying in the line before, which reads as follows:



        last_levels [h] [l] = 0;


        Unfortunately, h can be < 0. In this case, some kinda exception (array index out of bounds) should be thrown, but unfortunately, it isn't (Does anybody know why?). The gdb gave me the wrong information of the overwrite of is_ready to happen in the following line (Is this maybe a bug?), and I believed this without any criticism. As if this wasn't enough, this error made no problems until I changed my code in a completely different place!



        This blunder has cost me quite much time, but now, at last, I know what its cause was, and I corrected it successfully. Thank you anyway for your hints and comments!






        share|improve this answer













        After floating around the code line in question, I found out that the blunder was lying in the line before, which reads as follows:



        last_levels [h] [l] = 0;


        Unfortunately, h can be < 0. In this case, some kinda exception (array index out of bounds) should be thrown, but unfortunately, it isn't (Does anybody know why?). The gdb gave me the wrong information of the overwrite of is_ready to happen in the following line (Is this maybe a bug?), and I believed this without any criticism. As if this wasn't enough, this error made no problems until I changed my code in a completely different place!



        This blunder has cost me quite much time, but now, at last, I know what its cause was, and I corrected it successfully. Thank you anyway for your hints and comments!







        share|improve this answer












        share|improve this answer



        share|improve this answer










        answered Nov 23 '18 at 10:08









        NeppomukNeppomuk

        1731315




        1731315
































            draft saved

            draft discarded




















































            Thanks for contributing an answer to Stack Overflow!


            • Please be sure to answer the question. Provide details and share your research!

            But avoid



            • Asking for help, clarification, or responding to other answers.

            • Making statements based on opinion; back them up with references or personal experience.


            To learn more, see our tips on writing great answers.




            draft saved


            draft discarded














            StackExchange.ready(
            function () {
            StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53346531%2fcan-the-code-of-some-c-class-accidentally-overwrite-a-private-static-variable%23new-answer', 'question_page');
            }
            );

            Post as a guest















            Required, but never shown





















































            Required, but never shown














            Required, but never shown












            Required, but never shown







            Required, but never shown

































            Required, but never shown














            Required, but never shown












            Required, but never shown







            Required, but never shown







            Popular posts from this blog

            Xamarin.iOS Cant Deploy on Iphone

            Glorious Revolution

            Dulmage-Mendelsohn matrix decomposition in Python