bug-hurd
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[PATCH 4/4] device/chario.c (char_write): avoid segmentation fault


From: Marin Ramesa
Subject: [PATCH 4/4] device/chario.c (char_write): avoid segmentation fault
Date: Fri, 13 Dec 2013 21:06:55 +0100

The situation is that there is a pointer (source) that is being cast to
another pointer (target) and then the members of the target structure
pointed to by the target pointer are being used as if the content of
memory at the source address is a target structure, not source structure 
pointed to by the source pointer.

In the worst case (when source structure is smaller than the target
structure) this leads to segmentation fault, as is illustrated by
the following short program:

struct s1 {
        int x1;
        int x2;
};

struct s2 {
        int x3;
};

int main()
{       
        int x = 0;
        int y = 1;
        struct s1 *y1 = (struct s1 *)&x;
        struct s2 *y2 = (struct s2 *)&y;
        y1->x1 = 0;
        y1->x2 = 0;
        y2->x3 = 1;
        ((struct s1 *)y2)->x2;
        return 0;
}

In the better case (when target structure is smaller or equal to the
source structure and the source of the data in the source structure
is not the target structure) this leads to usage of incorrect values.

Check if the source of the data in the source structure
memory is a target structure data. Do this by comparing the 
length of the char values starting with the source address until 
null-termination to the size of the target structure. Start by 
initializing the counter to the size of the first member in the 
target structure. Then char values in memory are counted until 
null-termination, and finally the counted result is compared to the 
size of the target structure. If the values don't match, return from the 
function.

* device/chario.c (char_write) (i, temp): New variables.
(char_write): New do-while loop.
(char_write): New if statement.

---
 device/chario.c | 8 ++++++++
 1 file changed, 8 insertions(+)

diff --git a/device/chario.c b/device/chario.c
index 91bd8e8..d962c5c 100644
--- a/device/chario.c
+++ b/device/chario.c
@@ -268,6 +268,14 @@ io_return_t char_write(
            vm_map_copy_t copy = (vm_map_copy_t) data;
            kern_return_t kr;
 
+           int i = sizeof(int);
+           char *temp = data;
+       
+           do i++; while(*temp++ != '\0');
+
+           if (i != sizeof(struct vm_map_copy))
+               return KERN_INVALID_ARGUMENT;
+
            kr = vm_map_copyout(device_io_map, &addr, copy);
            if (kr != KERN_SUCCESS)
                return kr;
-- 
1.8.1.4




reply via email to

[Prev in Thread] Current Thread [Next in Thread]