linuxassemblyx86nasm

Read data from proc/sys/kernel/


I want to create a program to get info about the operating system. I tried using syscalls, but think that reading from systems files will be more faster (directly). So, I write a simple program to read data from file from directory /proc/sys/kernel/ and want to read files: osrelease, hostname, ostype and other.... So, I did supposed is just but isn't. When I read file hostname I got this:

����

If I read as superuser I get normal data

oleg

This is the code of my program:

global _start

section .data
file db "/proc/sys/kernel/hostname",0

section .bss
buf resb 1024
descriptor resb 4
len equ 1024


section .text
_start:

    mov eax, 5
    mov ebx, file
    mov ecx, 2
    int 80h
    mov [descriptor], eax

read:
    mov eax, 3  ;read text
    mov ebx, [descriptor];  
    mov ecx, buf    ;read to variable buf
    mov edx, len    ;size of bug
    int 80h     ;interrupt

print_text:
    mov edx, eax
    mov eax, 4
    mov ebx, 1
    mov ecx, buf
    int 80h

close_file:
    mov eax, 6
    mov ebx, [descriptor]
    int 80h

exit:
    mov eax, 1
    mov ebx, 0
    int 80h

So, I thought change name of file and can get other system information, but it's mistake, because I don't got result. So, I change path to file, compile project and execute program as super user and I don't get result. Nothing...

I can read all files except this directory (proc/sys/kernel).

I googled information about this problem and don't find similar problem. I think it is security of OS, but I only read info, don't write... I understand that using syscall more simple, but want to understand the structure of the OS. Why can't I read info from this directory?


Solution

  • mov ecx, 2
    

    A flags value of 2 for open() is O_RDWR. You're attempting to open the file read-write, which as a normal user you cannot do because it's writable only by root (mode 0644 on my system). Unix permission checks are done when you open the file, not on each individual read and write, so this fails even though you do not intend to actually write to the file.

    So the open call returns a negative error code (which you don't check for), you pass this as the fd to read which thus also fails with a negative error code (which you also don't check for) and thus your buffer still contains a bunch of zeros. You pass this negative error code as the length to write(), which interprets it as a huge positive number and writes out not only the zero bytes from buf, but also whatever garbage follows it in memory, until it runs off the end of your address space.

    This does work for me as root. I don't quite understand your last paragraph and can't tell whether it does or doesn't work for you in that case. If it doesn't, you may have securelevels or some other mechanism that prevents writing the file even as root. Note that some other files in /proc/sys/kernel are not writable even by root, e.g. /proc/sys/kernel/version which is 0444, so for those files your program will fail as above even if you are root.

    But since you don't care about writing the file, just use flags O_RDONLY which has the value 0. So xor ecx, ecx instead. With this change the program works for me as a normal user.

    Error checking throughout would be a good idea.