diff options
author | Paul Menage <menage@google.com> | 2008-06-12 18:21:49 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2008-06-12 21:05:41 -0400 |
commit | 6c826818ff55eae7702b778b5f8bdf765af3b2af (patch) | |
tree | dab51aca0d7b86ccdc820894a96fad163f3fcb91 /ipc/shm.c | |
parent | bcf8039ed45f56013c4afea5520bca7d909e5e61 (diff) |
/proc/sysvipc/shm: fix 32-bit truncation of segment sizes
sysvipc_shm_proc_show() picks between format strings (based on the
expected maximum length of a SHM segment) in a way that prevents gcc from
performing format checks on the seq_printf() parameters. This hid two
format errors - shp->shm_segsz and shp->shm_nattach are both unsigned
long, but were being printed as unsigned int and signed int respectively.
This leads to 32-bit truncation of SHM segment sizes reported in
/proc/sysvipc/shm. (And for nattach, but that's less of a problem for
most users).
This patch makes the format string directly visible to gcc's format
specifier checker, and fixes the two broken format specifiers.
Signed-off-by: Paul Menage <menage@google.com>
Cc: Nadia Derbey <Nadia.Derbey@bull.net>
Cc: Manfred Spraul <manfred@colorfullife.com>
Cc: Pierre Peiffer <peifferp@gmail.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'ipc/shm.c')
-rw-r--r-- | ipc/shm.c | 16 |
1 files changed, 8 insertions, 8 deletions
@@ -1058,16 +1058,16 @@ asmlinkage long sys_shmdt(char __user *shmaddr) | |||
1058 | static int sysvipc_shm_proc_show(struct seq_file *s, void *it) | 1058 | static int sysvipc_shm_proc_show(struct seq_file *s, void *it) |
1059 | { | 1059 | { |
1060 | struct shmid_kernel *shp = it; | 1060 | struct shmid_kernel *shp = it; |
1061 | char *format; | ||
1062 | 1061 | ||
1063 | #define SMALL_STRING "%10d %10d %4o %10u %5u %5u %5d %5u %5u %5u %5u %10lu %10lu %10lu\n" | 1062 | #if BITS_PER_LONG <= 32 |
1064 | #define BIG_STRING "%10d %10d %4o %21u %5u %5u %5d %5u %5u %5u %5u %10lu %10lu %10lu\n" | 1063 | #define SIZE_SPEC "%10lu" |
1064 | #else | ||
1065 | #define SIZE_SPEC "%21lu" | ||
1066 | #endif | ||
1065 | 1067 | ||
1066 | if (sizeof(size_t) <= sizeof(int)) | 1068 | return seq_printf(s, |
1067 | format = SMALL_STRING; | 1069 | "%10d %10d %4o " SIZE_SPEC " %5u %5u " |
1068 | else | 1070 | "%5lu %5u %5u %5u %5u %10lu %10lu %10lu\n", |
1069 | format = BIG_STRING; | ||
1070 | return seq_printf(s, format, | ||
1071 | shp->shm_perm.key, | 1071 | shp->shm_perm.key, |
1072 | shp->shm_perm.id, | 1072 | shp->shm_perm.id, |
1073 | shp->shm_perm.mode, | 1073 | shp->shm_perm.mode, |