-4

I need a global variable, which is able to set its read-write permission.

I am looking for an approach to change the permission of global variables during run time.

Is there any Linux system call support this?

e.g.

int GLOBAL_STATE = 123;

void process_state(){
//only in this function can the GLOBAL_STATE be modified.
//So that I can maintain the value of GLOBAL_STATE 
//The permission of GLOBAL_STATE must change to read-write.
...
}

void foo(){
//this function may cause an illegal pointer operator, 
//so GLOBAL_STATE may be modified. That is why the permission of
//GLOBAL_STATE must be change to read-only.
}
wangbo15
  • 191
  • 1
  • 13
  • 4
    If you can ensure that the array lives in its own memory page(s), then you could use `mprotect()` to write-protect it. I feel a latent need to question why you'd want to do that, though. – Dolda2000 Jun 04 '16 at 06:21
  • 2
    Take a look at http://stackoverflow.com/questions/6044141/making-c-module-variables-accessible-as-read-only – ReZa Jun 04 '16 at 06:32
  • 1
    @nimish : The question in the title is not the same as the question in the body - it appears that the access control must be dynamically controlled. – Clifford Jun 04 '16 at 08:19
  • @Dolda2000 Thank you for the tips. I have rewrite the question.And how can I get the page of the global variables ? How to set the page alignment allocated for all the global variables during coding stage ? – wangbo15 Jun 04 '16 at 12:46
  • @user153673 I am looking for the protection of the global variables during the run time, not for the good coding standard. Would you please give me some tips ? – wangbo15 Jun 04 '16 at 12:48
  • @Dolda2000 : I have tried the approach with `mmap` and `mprotect`. But I think the problem still exist. Although the protected page is read-only, the pointer of the page, a global pointer, still may be modified. Thus, I need to protect on the global variable. – wangbo15 Jun 05 '16 at 06:48

2 Answers2

3

Your question exhibits one of the several reasons why global variables are generally ill-advised. The generic (i.e. not OS specific) solution is to make the array static and hidden within a translation unit (i.e. not global) with public access functions which can then conditionally provide write access and also bounds-checking.

For example:

Array.c


#include <stdbool.h>

static int array[100] ;
static bool protected = false ;

int read_array( unsigned index )
{
    return array[index] ;
}

void protect_array()
{
    protected = true ;
}

void unprotect_array()
{
    protected = false ;
}

void write_array( unsigned index, int value )
{
    if( !protected && index < sizeof(array) )
    {
        array[index] = value ;
    }
}

size_t sizeof_array()
{ 
    return sizeof(array) ;
}

size_t lengthof_array()
{ 
    return sizeof(array) / sizeof(*array) ;
}

That provides global control of read/write access (i.e. at any time the array is either R/W or R/O. It may be that you want to simultaneously provide read/write access to some users and read-only to others. That can be achieved thus:

Array.c


static int array[100] ;
int* get_array_rw()
{ 
    return array ;
}

const int* get_array_ro()
{
    return array ;
}

size_t sizeof_array()
{ 
    return sizeof(array) ;
}

size_t lengthof_array()
{ 
    return sizeof(array) / sizeof(*array) ;
}

This method will catch write access attempts via the read-only pointer at compile time. However it still has most of the problems associated with global variables.

A less generic OS specific method is to use a memory-mapped file for the array and use the access control for the memory-mapped file to impose read-only or read-write semantics:

size_t array_len = 100 ;
int fd = open( "arrayfile", O_RDONLY, 0);

if( fd >= 0 )
{
    int* array = mmap( NULL, array_len * sizeof(int), PROT_READ, MAP_PRIVATE | MAP_POPULATE, fd, 0);

    // Now array points to read only memory 
    // accessible through normal pointer and array index operations.
}

A further method, but not within the scope of your question is to use C++ and wrap the array in a class and use operator overloading of [] to access the array. This method is identical to the first suggestion, but syntactically allows array-like access like the second and third.

Clifford
  • 88,407
  • 13
  • 85
  • 165
  • I have tried the approach with `mmap` and `mprotect`. But I think the problem still exist. Although the protected page is read-only, the pointer of the page, a global pointer, still may be modified. Thus, I need to protect on the global variable. I have update the problem description, would you please give me some advices? Thank you. – wangbo15 Jun 05 '16 at 06:54
0

One alternative is to export a constant pointer to the array.

Example:

M.h

extern const int *const M_a;

M.c

#include "M.h"

static int a[100];

const int *const M_a = a;
August Karlstrom
  • 10,773
  • 7
  • 38
  • 60