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: <008a01c39c26$fac28c10$7b00a8c0@BillDell>
From: full-disclosure at royds.net (Bill Royds)
Subject: [inbox] Re: RE: Linux (in)security

You are saying that a language that requires every programmer to check for
security problems on every statement of every program is just as secure as
one that enforces proper security as an inherent part of its syntax?
    And I suppose that you also believe in the tooth fairy.

 Yes, it is possible to write secure C code by having the discipline to not
use the
insecure language constructs such as strings and pointers and arrays (which
are the same as pointers)
You then need to invent your own data types as you just did with your
subroutine, which still risks a buffer overflow because strlen itself still
looks for the null byte at end of string and so can overflow
its internal counters. C is used to write software because it one step above
assembler language. It can do just about anything that the underlying
hardware can do without being absolutely architecture dependent. Many of its
features are there because the PDP-11 computer had machine instructions to
do the same thing (++ and -- correspond to PDP-11 INC and DEC instruction
for example). One can write machine efficient code in C, which is why Ken
Thompson developed it for writing the Unix operating system. Efficiency is
not security and whenever they was a choice in designing the language,
efficiency won over security or even readability.

 I have been programming in C since the 70's so I am quite aware of what the
language can do and
appreciate its power. But the power comes at the price of making it much
more difficult to handle the security and readability of C code. Since one
can do just about anything in C, the language compilers will not prevent you
from shooting yourself in the foot. Other languages restrict what you can
do, to prevent some security problems.
   But there is so much code out there that is written in C (or its bastard
child C++) that we are not going to get rid of it soon. Java would actually
be a good language if Sun would allow one to write compilers for it that
generated native machine language, not just Java byte code.  But the
conversion of the world programmer mindset to restricting use of insecure
language features will take eons so I give it no hope.

You ask
"Isn't it the programmer's job to *know* what types he's using and what his
pointers refer to?  And if he can't know, to error check?  It think we'd be
vastly better off teaching how to program properly than we would be trying
to devise a language that is idiot-proof. "

A programmer certainly can not know what his pointers refer to. That would
require the writer of a function to know all possible circumstances in which
the routine would be called and to somehow prevent her routine from being
linked in with code that calls it incorrectly. That is often called the
halting problem. Most security problems come from exactly the case that the
subroutine user "knows" what are the arguments for all calls in the original
use and handles those. The infinity of all other cases can not be checked at
run time without either significantly slowing down the code or risking
missing some.
   The recent MSBlaster worm is a case in point. The writers of the RPC code
"knew" that code within MS Windows never passed more than a 16 unicode
character (32 byte) machine name as one of its parameters so did not need to
check ( the argument was not of type wchar * but of type wchar[16]). Since C
actually does not implement arrays at all, but only uses  array syntax [] as
an alias for a pointer, the only way to prevent buffer overflow in a C
routine is to never allow string arrays  as parameters to functions,
complete obscuring the meaning of code.
The problem is that C encourages bad coding practice and obscures the actual
meanings of various data structures and even the code auditing techniques of
the OpenBSD crowd do not find all the possible mistakes
A language will never be goof-proof, but it should not make it easier to
goof than be correct.

----- Original Message ----- 
From: "Paul Schmehl" <pauls@...allas.edu>
To: <full-disclosure@...ts.netsys.com>
Sent: Sunday, October 26, 2003 5:15 PM
Subject: Re: [inbox] Re: [Full-Disclosure] RE: Linux (in)security


--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
  }

Granted you probably want to be more gracious handling errors than an
abrupt exit and you'd probably want to use a case statement to allow for
checking numerous different allowed lengths, but seriously - is a language
supposed to be goof proof?  Or are programmers supposed to learn how to do
it right?

How hard is it, really, to add a couple of lines to each input call - ok =
chk_str_len(buf), if {ok == 0} continue}else{ handle_error(ok)}?

(I'm sure there are more efficient ways to handle this than my simplistic
suggestion, but the point remains - handling buffer overflows should be
trivial to write in C.  The problem is that programmers simply don't think
about it (or don't even know about it) when they're writing the code.

>  Another problem with C is that there is not an inherent mechanism to
> match the types of parameters in a fnction call with the types of the
> actual parameters used, especially when calling with arrays or pointers.
> A pointer argument is inherently insecure because it could point to
> anything. The only mechanism for passing parameters that need to be
> changed by a function is a pointer in C (others have value/result where
> the subroutine makes a local copy modifies that then returns the modified
> value for caller to use).     If we really want to have more secure
> software we need to look at the tools we use to write it, not just at the
> platforms it runs on.
>
Isn't it the programmer's job to *know* what types he's using and what his
pointers refer to?  And if he can't know, to error check?  It think we'd be
vastly better off teaching how to program properly than we would be trying
to devise a language that is idiot-proof. b

Paul Schmehl (pauls@...allas.edu)
Adjunct Information Security Officer
The University of Texas at Dallas
AVIEN Founding Member
http://www.utdallas.edu

_______________________________________________
Full-Disclosure - We believe in it.
Charter: http://lists.netsys.com/full-disclosure-charter.html


Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ