Why do I keep getting a set fault when I try and pass -H in the command line as a flag? -h (help) is working perfectly but -H(header) messes up every single time.
I have a main function as well which calls parse_command_line by passing the argc & argc.
the bool is defined as bool header = false;
the file is char** file = NULL;
and the reason I have the file+=1; in the code is so that it compiles because I am using a makefile that changes all warnings into errors.
#include "parse.h" /* prototypes for exported functions */
#include "../main/unused.h"
#include <stdlib.h>
#include <getopt.h>
#include <stdio.h>
#include <stdint.h>
int
parse_command_line (int argc, char **argv, bool *header, char **file)
{
int oc = 0;
file += 1;
bool help = false;
struct option long_options[] =
{
{"header", no_argument, NULL, 'H'},
{"help", no_argument, NULL, 'h'},
{0, 0, 0, 0}
};
while ((oc = getopt_long(argc, argv, "+Hh", long_options, NULL)) != -1)
{
printf("The value of oc = %d\n", oc);
switch(oc)
{
case 'h':
help = true;
break;
case 'H':
printf("inside case H");
*header = true;
break;
case '?':
fprintf(stderr, "Unknown flag = -%c, type -h or --help for help!\n", optopt);
exit(EXIT_FAILURE);
break;
default:
break;
}
}
printf("Out of loop"); if (optind+1 != argc)
{
fprintf(stderr, "Uh oh, invalid input! Try again with -h or --help for help!\n");
exit(EXIT_FAILURE);
}
if (help)
{
printf("\nHaving some trouble? Let me show you the ropes!\n\n");
printf("Format: ydi <option(s)> mini-elf-file\n\n");
printf("Here's your options:\n");
printf("-h --help Display usage\n");
printf("-H --header Show the Mini-Elf header\n");
exit(1);
}
if (header)
{
printf("Inside HEader");
FILE *file;
uint16_t nums[6];
file = fopen(argv[optind], "r");
#define STRUCT_ITEMS 7
fread(nums, 16, 6, file);
int cur_print;
for (cur_print = 0; cur_print < STRUCT_ITEMS; cur_print++)
{
printf("%d ", nums[cur_print]);
}
}
return 0;
}
My parse.h file is as follows:
#ifndef __PARSE_COMMAND_LINE__
#define __PARSE_COMMAND_LINE__
#include <stdbool.h>
int parse_command_line (int argc, char **argv, bool *header, char **file);
#endif
There are other files such as elf.h and elf.c which I have not implemented and are not called at all at this point, which leads me to believe they are not going to be the problem and don't need to post the small 2 line files. My main function is as follows:
#include <stdio.h> /* standard I/O */
#include <stdlib.h>
#include "unused.h" /* UNUSED macro */
#include "../cmdline/parse.h" /* command line parser */
#include "../y86/elf.h" /* Mini-ELF format */
int
main (int argc UNUSED, char **argv UNUSED)
{
printf ("Congratulations, you have compiled your source code!\n");
bool header = false;
char **file = NULL;
parse_command_line (argc, argv, &header, file);
return 0;
}
And the file unused.h (because the compiler will make unused variables an error instead of warning) is as follows:
#ifndef __UNUSED__
#define __UNUSED__
#define UNUSED __attribute__ ((unused))
#endif
The code doesn't check the return value of fopen, which will be NULL in case of an error. Dereferencing NULL in the fread call causes a segfault.
Related
here is my code down below, the code is incomplete, but the problem is I have set the t as the only option I have for this program, and when i run it with option -t input, it gives me error as following:
./run: invalid option -- 't'
Option error !
there is my code:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/stat.h>
#include <error.h>
#include <string.h>
#define FALSE 0
#define TRUE 1
#define DEFAULT_SECOND 10
extern int errno;
int errnum;
FILE* fin = NULL;
int main (int argc, char* argv[])
{
int opt;
int tFlag = FALSE;
int defaultFlag = TRUE;
int sec;
while ((opt = getopt(argc,argv,"t:"))!=-1)
{
switch (opt)
{
case 't':
tFlag = TRUE;
defaultFlag = FALSE;
break;
case '?':
Printf("No such option, Now taking Exit...");
exit(EXIT_FAILURE);
default:
break;
}
}
for (int i = 0; i < argc - optind; ++i)
{
fin = fopen(argv[optind + i], "r");
if (fin == NULL)
{
errnum = errno;
fprintf(stderr, "Error opening file: %s\n", strerror(errnum));
exit(1);
}
if (defaultFlag == TRUE)
{
sec = defaultFlag;
}
if (tFlag == TRUE)
{
if((sec = atoi(optarg)==-1))
{
printf("input error!!");
exit(EXIT_FAILURE);
}
}
}
return 0;
}
please tell me if I have wrongfully set the option for -t, if possible please tell me where is the problem.
So I have this function in my driver for network NIC and this function appears in proc/kallsyms[https://stackoverflow.com/a/67766463/4808760] file with base address this is the function
static int rtl8169_poll(struct napi_struct *napi, int budget)
{
struct rtl8169_private *tp = container_of(napi, struct rtl8169_private, napi);
struct net_device *dev = tp->dev;
int work_done;
rtl_tx(dev, tp, budget);
work_done = rtl_rx(dev, tp, budget);
if (work_done < budget && napi_complete_done(napi, work_done))
rtl_irq_enable(tp);
return work_done;
}
appears as
ffffffffc02d2210 t rtl8169_poll [r8169]
and this is my ebpf program
SEC("kprobe/rtl8169_poll")
int bpf_prog2(struct pt_regs *ctx)
{
int sc_nr = (int)PT_REGS_PARM1(ctx);
char *fmt="HELLO from FWDALI %d %d";
bpf_trace_printk(fmt,1,sc_nr);
bpf_trace_printk(fmt ,2,sc_nr);
/* dispatch into next BPF program depending on syscall number */
//bpf_tail_call(ctx, &progs, sc_nr);
/* fall through -> unknown syscall */
//if (sc_nr >= __NR_getuid && sc_nr <= __NR_getsid) {
// char fmt[] = "-----FWD-------------------------syscall=%d (one of get/set uid/pid/gid)\n";
// bpf_trace_printk(fmt, sizeof(fmt), sc_nr);
//}
return 0;
}
And this is my simple userspace code
// SPDX-License-Identifier: GPL-2.0
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <linux/filter.h>
#include <linux/seccomp.h>
#include <sys/prctl.h>
#include <bpf/bpf.h>
#include <bpf/libbpf.h>
#include <sys/resource.h>
#include <fcntl.h>
#ifdef __mips__
#define MAX_ENTRIES 6000 /* MIPS n64 syscalls start at 5000 */
#else
#define MAX_ENTRIES 1024
#endif
/* install fake seccomp program to enable seccomp code path inside the kernel,
* so that our kprobe attached to seccomp_phase1() can be triggered
*/
void read_trace_pipe(void)
{
int trace_fd;
//printf("-%s-\n",DEBUGFS);
trace_fd = open( "/sys/kernel/debug/tracing/trace_pipe", O_RDONLY, 0);
if (trace_fd < 0)
return;
while (1) {
static char buf[4096];
ssize_t sz;
sz = read(trace_fd, buf, sizeof(buf) - 1);
if (sz > 0) {
buf[sz] = 0;
puts(buf);
}
}
}
static void install_accept_all_seccomp(void)
{
struct sock_filter filter[] = {
BPF_STMT(BPF_RET+BPF_K, SECCOMP_RET_ALLOW),
};
struct sock_fprog prog = {
.len = (unsigned short)(sizeof(filter)/sizeof(filter[0])),
.filter = filter,
};
if (prctl(PR_SET_SECCOMP, 2, &prog))
perror("prctl");
}
int main(int ac, char **argv)
{
struct bpf_link *link = NULL;
struct bpf_program *prog;
struct bpf_object *obj;
int key, fd, progs_fd;
const char *section;
char filename[256];
FILE *f;
snprintf(filename, sizeof(filename), "%s_kern.o", argv[1]);
obj = bpf_object__open_file(filename, NULL);
if (libbpf_get_error(obj)) {
fprintf(stderr, "ERROR: opening BPF object file failed\n");
return 0;
}
prog = bpf_object__find_program_by_name(obj, "bpf_prog2");
if (!prog) {
printf("finding a prog in obj file failed\n");
goto cleanup;
}
/* load BPF program */
if (bpf_object__load(obj)) {
fprintf(stderr, "ERROR: loading BPF object file failed\n");
goto cleanup;
}
link = bpf_program__attach(prog);
if (libbpf_get_error(link)) {
fprintf(stderr, "ERROR: bpf_program__attach failed\n");
link = NULL;
goto cleanup;
}
progs_fd = bpf_object__find_map_fd_by_name(obj, "progs");
if (progs_fd < 0) {
fprintf(stderr, "ERROR: finding a map in obj file failed\n");
goto cleanup;
}
bpf_object__for_each_program(prog, obj) {
section = bpf_program__section_name(prog);
/* register only syscalls to PROG_ARRAY */
if (sscanf(section, "kprobe/%d", &key) != 1)
continue;
fd = bpf_program__fd(prog);
bpf_map_update_elem(progs_fd, &key, &fd, BPF_ANY);
}
install_accept_all_seccomp();
f = popen("dd if=/dev/zero of=/dev/null count=5", "r");
(void) f;
read_trace_pipe();
cleanup:
bpf_link__destroy(link);
bpf_object__close(obj);
return 0;
}
SO i like if some take a look at above and explain what exactly I need to add to my ebpf program for kprobe and also what I need to do in my userspace loader program..
I am still having tough time with getting to loads of stuff that tells its simple to implement to use this magical line SEC("kprobe/rtl8169_poll") or something with just loading the program from userspace and its done, But I havent started thinking much of ebpf since ebpf is kind of failed in this simple function hook
this link gave me the idea that I can hook to this function https://stackoverflow.com/a/67766463/4808760
I have to make a custom shell as a school project and I'm hitting a wall with this:
int exec_shell(char **argv) //
{
if (execve(argv[0], (char **)argv , NULL)==-1) //if an error occurs
{
printf("Commande invalide : %s\n", argv[0]);
fflush(stdout);//vide le buffer
exit(0);
return -1;
}
return 0;
}
It's supposed to be very simple - you put in a command in string form and exec calls the said command.
However, it always returns an error.
What am I doing wrong?
Here is the single warning:
primitives.c:25:30: warning: deprecated conversion from string constant to ‘char*’ [-Wwrite-strings]
Step : 1
/* myecho.c */
#include <stdio.h>
#include <stdlib.h>
int
main(int argc, char *argv[])
{
int j;
for (j = 0; j < argc; j++)
printf("argv[%d]: %s\n", j, argv[j]);
exit(EXIT_SUCCESS);
}
Compile Program : gcc myecho.c -o myecho
step : 2
/* execve.c */
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
int
main(int argc, char *argv[])
{
char *newargv[] = { NULL, "hello", "world", NULL };
char *newenviron[] = { NULL };
if (argc != 2) {
fprintf(stderr, "Usage: %s <file-to-exec>\n", argv[0]);
exit(EXIT_FAILURE);
}
newargv[0] = argv[1];
if (execve(argv[1], newargv , newenviron) == -1) //if an error occurs
{
printf("Commande invalide : %s\n", argv[0]);
fflush(stdout);//vide le buffer
exit(0);
return -1;
}
}
compile program : gcc execve.c -o execve
step: 3 //Final call
./execve ./myecho
step: observe output.
To pass an empty environment either define and pass
char * env[] = { NULL };
as third parameter to execve() like this
execve(argv[0], argv, env)
or use a compound literal by doing
execve(argv[0], argv, (char*[]){NULL})
Also the members of the exec*() family of functions only return on error, so the surrounding code might look like this:
int main(void)
{
...
execve(argv[0], argv, (char*[]){NULL});
perror("execve() failed");
return EXIT_FAILURE; /* include stdlib.h to have this macro available */
}
[RESOLVED] Hey, I would like to thank you all for your answer. It helped me figure out better what was wrong and I found an answer here.
The main issue was the path not being correct.
While retrieving the broken-out fields of the record in the password database (e.g., the local password file /etc/passwd, NIS, and LDAP) that matches a provided username name, I am using the getpwnam_r (http://linux.die.net/man/3/getpwnam_r) function.
#define __USE_BSD
#define _BSD_SOURCE
#include <pwd.h>
#include <sys/types.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
int
main(int argc, char *argv[])
{
struct passwd pwd;
struct passwd *result;
char *buf;
size_t bufsize;
int s;
if (argc != 2) {
fprintf(stderr, "Usage: %s username\n", argv[0]);
exit(EXIT_FAILURE);
}
bufsize = sysconf(_SC_GETPW_R_SIZE_MAX);
if (bufsize == -1) /* Value was indeterminate */
bufsize = 16384; /* Should be more than enough */
buf = malloc(bufsize);
if (buf == NULL) {
perror("malloc");
exit(EXIT_FAILURE);
}
s = getpwnam_r(argv[1], &pwd, buf, bufsize, &result);
if (result == NULL) {
if (s == 0)
printf("Not found\n");
else {
errno = s;
perror("getpwnam_r");
}
exit(EXIT_FAILURE);
}
printf("Name: %s; UID: %ld\n", pwd.pw_gecos, (long) pwd.pw_uid);
exit(EXIT_SUCCESS);
}
The code works fine, but Eclipse shows me a warning as follows:
warning: implicit declaration of function ‘getpwnam_r’ [-Wimplicit-function-declaration]
How could I fix it?
Note that I'm currently using Ubuntu 14.04 LTS.
To use this function you need two includes :
#include <sys/types.h>
#include <pwd.h>
Add them and it should not complain anymore.
You can see that by running man getpwnam_r.
You also need to define either __USE_MISC or __USE_SVID since it a POSIX only function.
I am using gssapi in C for the first time. I am trying to reconstruct example on Oracle doc http://docs.oracle.com/cd/E19683-01/816-1331/sampleprogs-1/index.html.
In my .c file I call gss_str_to_oid(&min_stat, &tok, oid); and get an undefined reference error. I included #include "gssapi.h" at the top of my .c file. In gssapi.h there is a function call
OM_uint32 KRB5_CALLCONV
gss_str_to_oid(
OM_uint32 *, /* minor_status */
gss_buffer_t, /* oid_str */
gss_OID *);
So what am I doing wrong? I thought that if you included #include "gssapi.h" it would give me access to function in gssapi. Both files are in my src folder. So what am I doing wrong. I am using eclipse and from what in my makefile under targets it says all: GSS-API.
I am including most of my code below.
main
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
#include <error.h>
#include <sys/stat.h>
#include <fcntl.h>
#include "gssapi.h"
#include "gssapi_ext.h"
#include "gss-misc.h"
/* global mech oid needed by display status, and acquire cred */
FILE *display_file;
gss_OID g_mechOid = GSS_C_NULL_OID;
void usage()
{
fprintf(stderr, "Usage: gss-client [-port port] [-d]"
" [-mech mechOid] host service msg\n");
exit(1);
}
static void parse_oid(char *mechanism, gss_OID *oid)
{
char *mechstr = 0, *cp;
gss_buffer_desc tok;
OM_uint32 maj_stat, min_stat;
if (isdigit(mechanism[0])) {
mechstr = malloc(strlen(mechanism)+5);
if (!mechstr) {
printf("Couldn't allocate mechanism scratch!\n");
return;
}
sprintf(mechstr, "{ %s }", mechanism);
for (cp = mechstr; *cp; cp++)
if (*cp == '.')
*cp = ' ';
tok.value = mechstr;
} else
tok.value = mechanism;
tok.length = strlen(tok.value);
maj_stat = gss_str_to_oid(&min_stat, &tok, oid);
if (maj_stat != GSS_S_COMPLETE) {
// display_status("str_to_oid", maj_stat, min_stat);
return;
}
if (mechstr)
free(mechstr);
}
int main(argc, argv)
int argc;
char **argv;
{
/* char *service_name, *hostname, *msg; */
char *msg;
char service_name[128];
char hostname[128];
char *mechanism = 0;
u_short port = 4444;
int use_file = 0;
OM_uint32 deleg_flag = 0, min_stat;
display_file = stdout;
/* Parse arguments. */
argc--; argv++;
while (argc) {
if (strcmp(*argv, "-port") == 0) {
argc--; argv++;
if (!argc) usage();
port = atoi(*argv);
} else if (strcmp(*argv, "-mech") == 0) {
argc--; argv++;
if (!argc) usage();
mechanism = *argv;
} else if (strcmp(*argv, "-d") == 0) {
deleg_flag = GSS_C_DELEG_FLAG;
} else if (strcmp(*argv, "-f") == 0) {
use_file = 1;
} else
break;
argc--; argv++;
}
if (argc != 3)
usage();
if (argc > 1) {
strcpy(hostname, argv[0]);
} else if (gethostname(hostname, sizeof(hostname)) == -1) {
perror("gethostname");
exit(1);
}
if (argc > 2) {
strcpy(service_name, argv[1]);
strcat(service_name, "#");
strcat(service_name, hostname);
}
msg = argv[2];
if (mechanism)
parse_oid(mechanism, &g_mechOid);
/* if (call_server(hostname, port, g_mechOid, service_name,
deleg_flag, msg, use_file) < 0)
exit(1);*/
/*
if (g_mechOid != GSS_C_NULL_OID)
(void) gss_release_oid(&min_stat, &gmechOid);
*/
return 0;
}
gssapi.h
/* New for V2 */
OM_uint32 KRB5_CALLCONV
gss_str_to_oid(
OM_uint32 *, /* minor_status */
gss_buffer_t, /* oid_str */
gss_OID *);
You just can't include the header you have to link the library either dynamically or statically. Is there some dll, lib, so, etc you need to add to your project? Without makefile or your project setup been shown in your question; I think you will not receive a very clear answer. Just including header file isn't enough, the undefined is not a compilation error but a linker error, which means its missing a reference because you are not linking the library to your program.
The documentation for GSSAPI in C and C++ in not the greatest. Turns out you need to download gssapi. Here is the link http://www.gnu.org/software/gss/manual/gss.html.
It is under download and install
So, I faced same problem.
I found out that you need to add some .so files to your project.
Just in case check that your system has libkrb5-dev packet (most likely it is already installed if you have gssapi.h).
Required files are stored in folder "/usr/lib/x86_64-linux-gnu/" (debian in my case):
I added libkdb5.so and libgssapi_krb5.so to QT .pro file and all works fine:
LIBS += -lkdb5
LIBS += -lgssapi_krb5
If you need to find that files .so use folloing commands:
apt-file update
dpkg -L libkrb5-dev