Home > front end >  is this valid C plus valid ebpf, means can I safe the address of any object in long type which is 8
is this valid C plus valid ebpf, means can I safe the address of any object in long type which is 8

Time:08-22

this is my code

#include <stdio.h>
#include <string.h>
#include <stdint.h>
struct mystruct{
int i;
int j;
long k;
long l;
char str[11];

};
int main()
{

    struct mystruct obj;
    obj.i=5;obj.j=55;obj.k=6;obj.k=1000001;obj.l=2000007;memcpy(obj.str,"hello",sizeof("hello"));
    long addr=(long)((uint8_t *)&obj);
    struct mystruct *myobj=(struct mystruct *)(addr);
    printf("%d %d %zu %zu %s\n",myobj->i,myobj->j,myobj->k,myobj->l,myobj->str);
    printf("%zu=%zu\n",sizeof(long),sizeof(myobj));
    return 0;
}

So I like to know can I safe the address of any object (struct,union, etc.) or any type variable (int,long,char) into long variable. I showed the the code sizeof struct address or pointer is same as long. Is my above code is OK.

Also does ebpf varifier allows this?

Also if I have map with value of type long

struct {
    __uint(type, BPF_MAP_TYPE_HASH);
    __type(key, __u32);
    __type(value, long);
    __uint(max_entries, 2);
} hash_map1 SEC(".maps");

can I do extract my struct object like following from long type for map value

struct hash_elem {
    int cnt;
    struct bpf_spin_lock lock;
};

from long type. is this possible in ebpf/xdp?

CodePudding user response:

long addr=(long)((uint8_t *)&obj);
struct mystruct *myobj=(struct mystruct *)(addr);

I don't see a reason why the BPF verifier should reject this; you are just casting into and from long.

This will be compiled into a 64-bit BPF register anyway and type information will be lost (unless using BTF). The verifier will then infer a type for its own purpose and will correctly recognize this as a pointer to the stack (PTR_TO_STACK).


can I do extract my struct object like following from long type for map value

No, that wouldn't make sense. If you store in the map a pointer to the stack, then when your program exists, the pointer may be pointing to invalid memory.

CodePudding user response:

Why not simple:

    uintptr_t addr=(uintptr_t)&obj;
    struct mystruct *myobj=(struct mystruct *)(addr);

uintptr_t type is guaranteed to keep any pointer converted to an integer and it is widely used in the BPF code.

  • Related