lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite for Android: free password hash cracker in your pocket
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <3F9C578A.4060506@hutley.net>
From: brett at hutley.net (Brett Hutley)
Subject: [inbox] Re: RE: Linux (in)security

Paul Schmehl wrote:

> --On Sunday, October 26, 2003 12:45 PM -0500 Bill Royds 
> <full-disclosure@...ds.net> wrote:
> 
>> Actually there is a significant difference between OS that get a large
>> number of vulnerabilities released like Windows, Linux etc. and those OS
>> like VMS and OS/400 that do not.
>> The real difference is the programming language used to write the code.
>> The C programming language used for Windows, Linux etc. is inherently
>> insecure. The C string is an invitation to a buffer overflow. It has no
>> bounds checking by default so each use of it (copy, string search ...)
>> must be checked for a buffer overflow.
> 
> 
> You mean, as a programmer, it's not possible to write a library function 
> that checks string lengths and simply call it for every buffer?
> 
> Like (in pseudocode)?
> 
> chk_str_len(buf) {
>  if (buf>256) {
>    print "Error!  Input larger than allocated buffer!"
>    return err_num
>  }else{
>    return 0
>  }

*snip*
Ahhh nope.
What about the following?

char buf[10];
const char *str1 = "OVER";
const char *str2 = "FLOW!!!!!";
sprintf(buf, "%s%s", str1, str2);

Admittedly a contrived example. The best way to handle this type of 
stuff is to provide "safe" functions - like a sprintfn() that takes the 
maximum size of the buffer to write into as an argument. This function 
is reasonably tricky to write however. Consider the following example:

double x;
char buf[10];
/* loop and add up some values in x */
sprintf(buf, "%f\n", x);

Note that x has been accidently left uninitialized by the programmer. 
Now in testing the variable "x" happened to be initialized to zero, but 
whats say the stack happens to contain the value 123456780.9 in the area 
of memory that belongs to x when the function is called?

Also using these type of functions in operating system code is a good 
way to create a *REALLY*  S L O W system. In maybe 80% of system code 
you are going to know who ALL the callers of the function are and are 
going to be working with input that has already been validated further 
up the call tree. Why slow this code down with unnecessary checks? 
Validation of input is important when the input is specified by 
something external to the system - user parameters, environment variables...

Cheers, Brett
-- 
Brett Hutley [MAppFin,CISSP,SANS GCIH]
mailto:brett@...ley.net
http://hutley.net/brett



Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ