linux
Use of variable before initialization when !SECURITY
reiserfs_security_init() assumes that `length' will be initialized by security_old_inode_init_security(), if this succeeds. But the mockup implementation of security_old_inode_init_security() for !SECURITY succeeds and lefts `length' uninitialized. Note that `length' is a local variable hence, prior to initialization, it can hold any value.
Bug fixed by commit 30e053248da
Type | UninitializedVariable |
Config | "REISERFS_FS_SECURITY && !SECURITY" (2nd degree) |
Fix-in | code |
Location | fs/reiserfs/ |
__attribute__ ((noinline)) int nondet() { return 42; } #ifdef CONFIG_SECURITY int security_old_inode_init_security(int *len) { if (nondet()) { *len = 0; return 0; } else return -1; } #else int security_old_inode_init_security(int *len) { return 0; } #endif int reiserfs_security_init(int *length) { int error; error = security_old_inode_init_security(length); // (4) length is never written if !SECURITY if (error) { // (5) guaranteed false if !SECURITY *length = 0; return error; } int x = *length; // (6) ERROR return 0; } int reiserfs_create() { int retval; int length; // (2) retval = reiserfs_security_init(&length); // (3) length not initialized if (retval < 0) { return retval; } return 0; } int main(void) { reiserfs_create(); // (1) return 0; }
diff --git a/simple/30e0532.c b/simple/30e0532.c --- a/simple/30e0532.c +++ b/simple/30e0532.c @@ -1,3 +1,5 @@ + +#define EOPNOTSUPP 95 /* Operation not supported on transport endpoint */ __attribute__ ((noinline)) int nondet() { return 42; } @@ -14,7 +16,7 @@ #else int security_old_inode_init_security(int *len) { - return 0; + return -EOPNOTSUPP; } #endif
#include <stdlib.h> int main(int argc, char** argv) { // reiserfs_create(); int retval; int length; int error; // error = security_old_inode_init_security(length); #ifdef CONFIG_SECURITY if (rand() % 2) { length = 0; error = 0; } else error = -1; #else error = 0; #endif if (error) { length = 0; retval = error; } if (length) { // ERROR // do something } if (retval < 0) { return retval; } return 0; }
. call fs/reiserfs/namei.c:575:reiserfs_create() . 586: struct reiserfs_security_handle security; . 596: retval = reiserfs_security_init(dir, inode, &dentry->d_name, &security); .. call fs/reiserfs/xattr_security.c:56:reiserfs_security_init() .. 69: error = security_old_inode_init_security(inode, dir, qstr, &sec->name, &sec->value, &sec->length); .. 79: } .. ERROR 81: if (sec->length && reiserfs_xattrs_initialized(inode->i_sb))