You are not logged in.

#1 2018-09-29 01:50:46

jbenge1
Member
From: Az
Registered: 2018-04-09
Posts: 151

[SOLVED]C how to get a random byte in custom driver

I wanted to get some practice in C. So I decided that I would build a play driver that when read will return a however many random bytes requested. I've more or less (at least I think) got it working however I wanted to add functionality for having a maximum byte value. Here is the code

#include <linux/fs.h>
#include <linux/init.h>
#include <linux/miscdevice.h>
#include <linux/module.h>

#include <linux/uaccess.h>
#include <linux/random.h>

unsigned char random_byte(int max)
{
        unsigned char some_char;
        get_random_bytes(&some_char, 1);
        return some_char%max;
}

static ssize_t rand_driver_read(struct file * file, char * buf, 
                          size_t count, loff_t *ppos)
{
        int i;
        unsigned char num_bytes_read = 0;
        for(i=0;i<count;i++)
        {
                unsigned char c = random_byte(10);
                if(copy_to_user(buf, &c, 1))
                        return -EINVAL;
                num_bytes_read++;
        }
        *ppos += num_bytes_read;
        return num_bytes_read;
}

What I've been using to test it is just a simple C program at the moment

int main()
{
    int fd = open("/dev/rand_driver", O_RDWR);
    char *buf;
    int read_ret = read(fd, buf, 5);
    printf("read returned the value of %d\n", read_ret);
    for(int i=0;i<5;i++)
        printf("Random number at pos %d was %d\n", i, buf[i]);
    return 0;
}

The first random number is what I expect, However the next five numbers are all just random (possibly garbage) numbers. Some exapmle output would be

read returned the value of 5
Random number at pos 0 was 8
Random number at pos 1 was -2
Random number at pos 2 was -117
Random number at pos 3 was -65
Random number at pos 4 was 64

I've tried updating buf in the read implementation so something like *buf+=1. I also tried just creating a temporary buffer, filling it, and then copying everything over using copy_to_user(buf, temp, count);
All to no avail. Any hints or tips?

Edit: When checking the return values for any erros The file_descriptor that is returned is 3 (not sure if that matters or not) and the value returned by read is 5 which is what I expected as well.

Last edited by jbenge1 (2018-09-29 02:55:33)


"Dr. Madden, why don't the natural numbers include 0?" -me
"....... Take a philosophy course" -Dr. Madden

Offline

#2 2018-09-29 02:07:18

Trilby
Inspector Parrot
Registered: 2011-11-29
Posts: 29,449
Website

Re: [SOLVED]C how to get a random byte in custom driver

First check the return value of "read" (and "open" while you're at it).  Don't bother speculating on what *might* have gone wrong before you even put the most basic error checking into the code.

Last edited by Trilby (2018-09-29 02:08:21)


"UNIX is simple and coherent..." - Dennis Ritchie, "GNU's Not UNIX" -  Richard Stallman

Offline

#3 2018-09-29 02:11:11

jbenge1
Member
From: Az
Registered: 2018-04-09
Posts: 151

Re: [SOLVED]C how to get a random byte in custom driver

I have already checked my return values I just stripped them from the final result for brevity, I will update my original post though!


"Dr. Madden, why don't the natural numbers include 0?" -me
"....... Take a philosophy course" -Dr. Madden

Offline

#4 2018-09-29 02:25:07

skunktrader
Member
From: Brisbane, Australia
Registered: 2010-02-14
Posts: 1,538

Re: [SOLVED]C how to get a random byte in custom driver

buf is never initialized

Offline

#5 2018-09-29 02:37:23

jbenge1
Member
From: Az
Registered: 2018-04-09
Posts: 151

Re: [SOLVED]C how to get a random byte in custom driver

When i initalize buf (by the following, not sure if its correct)

char *buf = malloc(5); 
if(buf == NULL)
{
    perror("Malloc failure");
    return -1;
}

I still get the same issue. That is the first position of buf is correct (a number between 1 and max) and the rest is nonesense. (well in this case 0, rather than garbage)


"Dr. Madden, why don't the natural numbers include 0?" -me
"....... Take a philosophy course" -Dr. Madden

Offline

#6 2018-09-29 02:40:07

skunktrader
Member
From: Brisbane, Australia
Registered: 2010-02-14
Posts: 1,538

Re: [SOLVED]C how to get a random byte in custom driver

And what about incrementing buf here

if(copy_to_user(buf, &c, 1))

you are overwriting the first character each time through the loop

Last edited by skunktrader (2018-09-29 02:41:06)

Offline

#7 2018-09-29 02:44:47

jbenge1
Member
From: Az
Registered: 2018-04-09
Posts: 151

Re: [SOLVED]C how to get a random byte in custom driver

jbenge1 wrote:

I've tried updating buf in the read implementation so something like *buf+=1. I also tried just creating a temporary buffer, filling it, and then copying everything over using copy_to_user(buf, temp, count);

I've tried that, though possibly I am incrementing buf incorrectly?


"Dr. Madden, why don't the natural numbers include 0?" -me
"....... Take a philosophy course" -Dr. Madden

Offline

#8 2018-09-29 02:47:55

skunktrader
Member
From: Brisbane, Australia
Registered: 2010-02-14
Posts: 1,538

Re: [SOLVED]C how to get a random byte in custom driver

buf++ or &buf[i]

Last edited by skunktrader (2018-09-29 02:48:06)

Offline

#9 2018-09-29 02:55:17

jbenge1
Member
From: Az
Registered: 2018-04-09
Posts: 151

Re: [SOLVED]C how to get a random byte in custom driver

big_smile Thank you!! I'm assuming then dereferencing the pointer was incorrect. Looking back though, i don't know why I thought it would... Probably time to brush up on my pointer arithmetic (and probably pointers in general lol)


"Dr. Madden, why don't the natural numbers include 0?" -me
"....... Take a philosophy course" -Dr. Madden

Offline

Board footer

Powered by FluxBB