Reading Garbage with shmget - c

I have created two processes. One of them creates a shared memory chunk and the other tries to read it. There are no compilation errors with this code but somehow Process 2 behaves weird.
Process 1:
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <sys/sem.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>
#include <signal.h>
#define nDEVICES 3
#define DEVICE_NAME_LIMIT 20
typedef struct d_list
{
char d_name[DEVICE_NAME_LIMIT];
int d_id;
}device_mapping;
int main()
{
key_t shared_memkey_D=ftok(".", 'D');
int shared_memid_D=shmget(shared_memkey_D, nDEVICES*sizeof(device_mapping), 0777|IPC_CREAT|IPC_EXCL);
device_mapping *DEVICES = (device_mapping*)shmat(shared_memid_D,0,0);
strcpy(DEVICES[0].d_name, "DISK");
strcpy(DEVICES[1].d_name, "PORT");
strcpy(DEVICES[2].d_name, "PRINTER");
DEVICES[0].d_id=1;
DEVICES[1].d_id=3;
DEVICES[2].d_id=2;
}
Process 2:
#include <stdio.h>
#include <errno.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <sys/sem.h>
#include <signal.h>
#define nDEVICES 3
#define DEVICE_NAME_LIMIT 20
typedef struct d_list
{
char d_name[DEVICE_NAME_LIMIT];
int d_id;
}device_mapping;
int main()
{
key_t shared_memkey_D=ftok(".", 'D');
int shared_memid_D=shmget(shared_memkey_D, nDEVICES*sizeof(device_mapping), 0777);
device_mapping *DEVICES = (device_mapping*)shmat(shared_memid_D,0,0);
int i=0;
for (i=0; i<nDEVICES; i++)
printf("%s\t%d\n", DEVICES[i].d_name, DEVICES[i].d_id);
}
Process 2 is reading all garbage and I cannot figure out what is going wrong after several attempts. Please help.
EDIT:
I had copied the wrong program here. I have made the corrections. Its still giving me garbage.
Process 2 prints the following:
DISK 11038
?FG+ 3
#?FG+ 2

/* process 1 */
typedef struct d_list
{
char d_name[DEVICE_NAME_LIMIT];
int d_id;
}device_mapping;
and
/* process 2 */
typedef struct d_list
{
char * d_name;
int d_id;
}device_mapping;
are not the same.
Change device_mapping definition for process 2 to be the same as for process 1, using characters arrays but character pointers.
For process 1 d_name uses DEVICE_NAME_LIMIT bytes, for process 2 d_name uses 4 bytes (32bit) or 8 bytes (64bit).
I'd put the common structure definitions into a shared header file, which is included by both pocesses' sources.

Related

XDP alternate to bpf_get_current_pid

How do I fetch current process id in xdp
my program:
#include <linux/bpf.h>
#include <linux/if_ether.h>
#include <linux/ip.h>
#include <linux/in.h>
#include <linux/udp.h>
#include <linux/sched.h>
#include <linux/if_packet.h>
#include <linux/if_vlan.h>
#include <uapi/linux/bpf.h>
#include <net/sock.h>
#include <bcc/proto.h>
int udpfilter(struct xdp_md *ctx) {
bpf_trace_printk("got a packet\n");
u32 cpu = bpf_get_smp_processor_id();
//bpf_trace_printk("%s looking\n",cpu);
u32 pid = bpf_get_current_pid_tgid();
return XDP_DROP;
}
Is there any alternate function to fetch current pid in xdp, I was taking reference of this https://github.com/iovisor/bcc/blob/master/docs/kernel-versions.md#program-types
Reading your other questions, I'm guessing you're trying to retrieve the PID of the destination process for the packet. That is not possible at the XDP hook because that information is simply not computed by the kernel yet.

Segmentation fault setup semaphore function

I got the shared_memory.c file where I'm declaring my functions. One of the functions will be setupSemaphoreRead().
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <pthread.h>
#include <sys/sem.h>
#include <semaphore.h>
#include <fcntl.h>
#include "shared_memory.h"
//more code...
int setupSemaphoreRead(){
sem_unlink(SEM_CONSUMER_FNAME);
sem_unlink(SEM_PRODUCER_FNAME);
sem_t *sem_prod = sem_open (SEM_PRODUCER_FNAME, O_CREAT | O_EXCL, 0666, 0);
if (sem_prod == SEM_FAILED) {
perror("sem_open/producer");
return -1;
}
sem_t *sem_cons = sem_open (SEM_CONSUMER_FNAME, O_CREAT | O_EXCL, 0666, 1);
if (sem_cons == SEM_FAILED) {
perror("sem_open/consumer");
return -1;
}
return 1;
}
//more code...
I got the signature declared at my header file
int setupSemaphoreRead();
//filenames for two semaphores
#define SEM_PRODUCER_FNAME "myproducer"
#define SEM_CONSUMER_FNAME "myconsumer"
In my main read program I'm trying to use the function in the fallowing way:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/sem.h>
#include <semaphore.h>
#include <pthread.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include "shared_memory.h"
...
sem_t *sem_cons;
sem_t *sem_prod;
setupSemaphoreRead();
...
I don't get any error when compiling the code, but when executing I got Segmentation fault (core dumped)
setupSemaphoreRead() assigns to sem_t * local variables. When it returns those variables are out of scope. It has no access to variables of the same name in the other scope. You need to study more how variable scopes work in C. A typical way to do what you're trying to do is have a function accept double-pointer arguments like:
int setupSemaphoreRead(sem_t** sem_cons, sem_t** sem_prod) {
*sem_cons = ...
..
and use it like:
sem_t* sem_cons;
sem_t* sem_prod;
int ret = setupSempahoreRead(&sem_cons, &sem_prod);
// Make sure to check the value of ret
You have
sem_t *sem_prod
both inside the function and inside main. In other words - they are different variables, i.e. the variables in main are not updated by the function.

How do I use user_regs_struct on ARM processor in ptrace-based debugger

I am following the code in Chapter 3 of "Learning Linux Binary Analysis". The code is, "A simple ptrace-based debugger".
I am trying to write this in my Raspberry Pi 3, which has an ARM processor. I know that the error means that I have not included the correct header file, but I cannot find what the correct header file is.
I get this error message:
field ‘pt_reg’ has incomplete type struct user_regs_struct pt_reg
After doing some research, I found asm/ptrace.h, which includes some macros for the registers struct specific to ARM. Am I on the right track? How in the world can I make this work with an ARM processor?
Here are the headers:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <errno.h>
#include <signal.h>
#include <elf.h>
#include <sys/types.h>
#include <sys/user.h>
#include <sys/stat.h>
#include <sys/ptrace.h>
#include <sys/mman.h>
typedef struct handle {
Elf64_Ehdr *ehdr;
Elf64_Phdr *phdr;
Elf64_Shdr *shdr;
uint8_t *mem;
char *symname;
Elf64_Addr symaddr;
struct user_regs_struct pt_reg;
char *exec;
} handle_t;

Working with libdpkg in C

I looked into the "dpkg-query" source-code and tried to get the list of installed packages.
It compiles, but when i try to run i get the fault at modstatdb_open() function.
#define LIBDPKG_VOLATILE_API 1
#include <stdio.h>
#include <unistd.h>
#include <dpkg/macros.h>
#include <dpkg/dpkg.h>
#include <dpkg/dpkg-db.h>
#include <dpkg/pkg-array.h>
#include <dpkg/debug.h>
#include <dpkg/pkg-list.h>
void main()
{
struct pkg_array array;
modstatdb_open(msdbrw_readonly | msdbrw_available_readonly);
pkg_array_init_from_db(&array);
printf("%d\n",array.n_pkgs);
pkg_array_destroy(&array);
modstatdb_shutdown();
}
Segmentation fault (core dumped)
What is wrong there?
Working version.
It has to use dpkg_program_init(char *progname); before all.
#define LIBDPKG_VOLATILE_API 1
#include <stdio.h>
#include <unistd.h>
#include <dpkg/dpkg.h>
#include <dpkg/dpkg-db.h>
#include <dpkg/pkg-array.h>
void main()
{
struct pkgset *set;
struct pkginfo *inf;
struct pkg_array array;
dpkg_program_init("a.out");
modstatdb_open(msdbrw_available_readonly);
pkg_array_init_from_db(&array);
printf("Number of packages in local database: %d\n",array.n_pkgs);
inf = pkg_db_find_singleton("kate");
printf("status code of package: %d\n", inf->status);// 7 means installed
dpkg_program_done();
}

Getter & Setter in C

i'm facing a problem in C where i'm trying to use some getter and setter to share a variable between multiple source file.
I declare here my variable (ok_button) with a getter and a setter:
variable.c
#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
#include <string.h>
#include "../libhd_src/libhd.h"
int ok_button;
void set_ok_button(int value){
ok_button=value;
printf("Setting ok");
}
int get_ok_button(){
return ok_button;
}
Here, when i push a button, it sets the variable to 1. (Can't upload the full code of this source file, but i see in my logs that the function set_ok_button is correctly execuded when i press (i see the printf "Setting OK" everytime i press my button))
button.c
#include "../libhd_src/libhd.h"
#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
#include <math.h>
#include <time.h>
void * button_back_center_short(void *arg){
set_ok_button(1);
return 0;
}
And here, i simply check the value of my variable with the getter function.
read.c
#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
#include <math.h>
#include <time.h>
#include "../../libhd_src/libhd.h"
int main(int argc, char **argv){
while(1){
printf("Value %d", get_ok_button());
usleep(500000);
}
}
The problem is that the value shown in read.c is always "0" even when i press my button and set the value to 1...
Does someone understand what's wrong ? Feel free to tell me if you see a better solution to do that :)
I think your problem may be that you have multiple set_ok_button and get_ok_button functions in different files. Make sure you only have them defined in one file, and in a header add 2 lines declaring (but not defining) the functions:
void set_ok_button(int value);
int get_ok_button();

Resources