Skip to contentSkip to conversation

Fix off-by-one after readlink() call

PATCH Superseded Thomas Jarosch 4 participants 7 messages Oct 14, 2011 – Oct 17, 2011

lore
Share & tools
lore
#0 lore raw

PATCH 1/1 Fix off-by-one after readlink() call

---
 tools/slub/slabinfo.c |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)
tools/slub/slabinfo.c +1 -1
index 868cc93..cc1a378 100644
@@ -1145,7 +1145,7 @@ static void read_slab_dir(void)
 		switch (de->d_type) {
 		   case DT_LNK:
 			alias->name = strdup(de->d_name);
-			count = readlink(de->d_name, buffer, sizeof(buffer));
+			count = readlink(de->d_name, buffer, sizeof(buffer)-1);
 
 			if (count < 0)
 				fatal("Cannot read symlink %s\n", de->d_name);
Signature · 1 line
1.7.6.4
#1 lore raw

tools/slub/slabinfo.c static void read_slab_dir(void) · line 1149

Quoted 10 lines · Thomas Jarosch

index 868cc93..cc1a378 100644

tools/slub/slabinfo.c +1 -1
@@ -1145,7 +1145,7 @@ static void read_slab_dir(void)
 		switch (de->d_type) {
 		   case DT_LNK:
 			alias->name = strdup(de->d_name);
-			count = readlink(de->d_name, buffer, sizeof(buffer));
+			count = readlink(de->d_name, buffer, sizeof(buffer)-1);
 

readlink required that the buffer size be specified.

READLINK(2) Linux Programmer's Manual READLINK(2)

NAME
readlink - read value of a symbolic link

SYNOPSIS

       #include <unistd.h>

       ssize_t readlink(const char *path, char *buf, size_t bufsiz);

Feature Test Macro Requirements for glibc (see feature_test_macros(7)):

       readlink(): _BSD_SOURCE || _XOPEN_SOURCE >= 500 || _POSIX_C_SOURCE >= 200112L

DESCRIPTION
readlink() places the contents of the symbolic link path in the buffer buf, which has size bufsiz. readlink() does not append a null byte to buf. It will truncate the contents (to a length of bufsiz characters), in case the buffer is too small to hold all of the contents.

#2 lore raw
Quoted 7 lines · Christoph Lameter
Quoted 7 lines

index 868cc93..cc1a378 100644

tools/slub/slabinfo.c +0 -0
@@ -1145,7 +1145,7 @@ static void read_slab_dir(void)
 		switch (de->d_type) {
 		   case DT_LNK:
 			alias->name = strdup(de->d_name);
Quoted 8 lines

tools/slub/slabinfo.c static void read_slab_dir(void) · line 1149

Quoted 3 lines
tools/slub/slabinfo.c +1 -1
-			count = readlink(de->d_name, buffer, sizeof(buffer));
+			count = readlink(de->d_name, buffer, sizeof(buffer)-1);
 

DESCRIPTION
readlink() places the contents of the symbolic link path in the buffer buf, which has size bufsiz. readlink() does not append a null byte to buf. It will truncate the contents (to a length of bufsiz characters), in case the buffer is too small to hold all of the contents.

The problem is the line after the readlink() call:

buffer[count] = '\0';

The common technique is to reduce the buffer size by one. Another fix would be to check

"
if (count < 0 || count == sizeof(buffer))

    fatal();

"

Reducing the buffer size by one is easier IMHO.

Cheers,
Thomas

#4 lore raw
In reply to Thomas Jarosch
Quoted 7 lines · Thomas Jarosch

The problem is the line after the readlink() call:

buffer[count] = '\0';

The common technique is to reduce the buffer size by one. Another fix would be to check

Quoted 7 lines

"
if (count < 0 || count == sizeof(buffer))

    fatal();

"

Reducing the buffer size by one is easier IMHO.

I think this should be used for changelog.

#5 lore raw
Quoted 14 lines · David Rientjes
Quoted 12 lines · Thomas Jarosch

The problem is the line after the readlink() call:

buffer[count] = '\0';

The common technique is to reduce the buffer size by one. Another fix would be to check

"
if (count < 0 || count == sizeof(buffer))
    fatal();
"

Quoted 6 lines
Quoted 2 lines

Reducing the buffer size by one is easier IMHO.

I think this should be used for changelog.

Thomas, please resend with proper changelog and with David's and Christoph's ACKs included.

#6 lore raw

PATCH v2 1/1 Fix off-by-one buffer corruption after readlink() call

readlink() never zero terminates the provided buffer. Therefore we already do

    buffer[count] = 0;

This leads to an off-by-one buffer corruption as readlink() might return the full size of the buffer.

The common technique is to reduce the buffer size by one. Another fix would be to check

"
if (count < 0 || count == sizeof(buffer))

    fatal();

"

Reducing the buffer size by one is easier IMHO.

---
 tools/slub/slabinfo.c |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)
tools/slub/slabinfo.c +1 -1
index 868cc93..cc1a378 100644
@@ -1145,7 +1145,7 @@ static void read_slab_dir(void)
 		switch (de->d_type) {
 		   case DT_LNK:
 			alias->name = strdup(de->d_name);
-			count = readlink(de->d_name, buffer, sizeof(buffer));
+			count = readlink(de->d_name, buffer, sizeof(buffer)-1);
 
 			if (count < 0)
 				fatal("Cannot read symlink %s\n", de->d_name);
Signature · 1 line
1.7.6.4