LSeek Weirdness or My Weirdness?

LSeek Weirdness or My Weirdness?

Post by Christoph Badu » Sat, 30 Oct 1993 20:23:16




Quote:>That's what I thought and that's what my original posting commented on.
>There's no way to tell the difference between lseek retuning -1 because of
>an error or -1 because some dumb driver (like the pseudotty in SunOS 4.1.1)
>happily accepts any seek.

Of course there is:

        lseek(fd, 0L, 0);
        errno = 0;
        off = lseek(fd, -1L, 1);
        if (off == -1 && errno != 0)
                perror("lseek");
        else
                /* good */
--

    Sie reagieren rein mathematish, nicht vernuenftig.
                                -- Cliff Allistair McLane, Orion VIII

 
 
 

LSeek Weirdness or My Weirdness?

Post by Chris Tor » Mon, 01 Nov 1993 05:52:25


In all of the commentary on lseek, I have not seen anyone describe
what *really* happens.

The lseek() call normally just updates the kernel's file table offset
as needed, then returns.  Older kernels also check to make sure that
the resulting offset is non-negative (as the documentation claims).
(In 4.4BSD this nonsense is gone; file offsets can be up to 2^63 anyway.)

Why, then, do some files accept negative offsets, while others reject
them?  The answer lies in, of all places, /dev/null.

The null, memory, and kernel memory pseudo-devices in many UNIX kernels
share a major device number (on Suns, for instance, major device 3, under
both SunOS and 4.4BSD---I tried to number my devices the same as Sun's).
Now, as it happens, on the VAX, `kernel memory' is anything whose virtual
address is in [0x80000000 .. 0xbfffffff].  This is a property of the
hardware.  These addresses, when treated as integers, are negative!

Now, most UNIX systems have *some* history that dates back to a VAX.
Even if your particular kernel has no VAX-specific code in its
ancestry, it probably has some VAX-influenced code.  One of these
influences is that lseek must accept `negative' offsets for seeks on
/dev/kmem.  Some kernels implement this by allowing negative seeks only
on the corresponding character major device; others allow it only on
all character devices; still others (such as 4.4BSD) eliminate all the
special-casing and just plain allow it.

Those systems that have special cases usually have bugs---sometimes
minor, sometimes serious---in which negative offsets on some devices
(such as ttys) cause mysterious behavior.  (I vaguely recall one case
where I got a system to panic.)  These bugs tend to creep in because
device-driver authors forget that negative offsets are possible.  Thus,
odd as it may seem, eliminating this special case actually reduces
errors.

None of this helps any if you have a system that misbehaves when using
negative offsets, but to fix that, you must have kernel source.
--
In-Real-Life: Chris Torek, Lawrence Berkeley Lab CSE/EE (+1 510 486 5427)


 
 
 

LSeek Weirdness or My Weirdness?

Post by Vincent Partingt » Sat, 06 Nov 1993 18:25:42



>>That's what I thought and that's what my original posting commented on.
>>There's no way to tell the difference between lseek retuning -1 because of
>>an error or -1 because some dumb driver (like the pseudotty in SunOS 4.1.1)
>>happily accepts any seek.
>Of course there is:
>    lseek(fd, 0L, 0);
>    errno = 0;
>    off = lseek(fd, -1L, 1);
>    if (off == -1 && errno != 0)
>            perror("lseek");
>    else
>            /* good */

I'm afraid that won't work, because errno is not cleared on succesfull calls,
so you may be looking at an old returncode from a previous systemcall.
Here's an excerpt from the SunOS 4.1.1 manual page intro(2):

     Most of these calls have one  or  more  error  returns.   An
     error  condition  is  indicated  by  an otherwise impossible
     return value.  This is almost always  `-1';  the  individual
     descriptions  specify  the  details.   An error code is also
     made available in the external variable errno.  errno is not
     cleared  on  successful  calls,  so it should be tested only
     after an error has been indicated.   Note:   several  system
     calls  overload the meanings of these error numbers, and the
     meanings must be interpreted according to the type and  cir-
     cumstances of the call.  See ERROR CODES below for a list of
     system error codes.

I think this is a flaw in the system. I think lseek should always return an
error (EINVAL) when seeking to negative offsets.

Vincent.
--


        Dennis Ritchie when born           FidoNet  : 2:281/202.15
                                           NeST     : 90:500/202.15

 
 
 

LSeek Weirdness or My Weirdness?

Post by Vincent Partingt » Sat, 06 Nov 1993 18:31:27



>In all of the commentary on lseek, I have not seen anyone describe
>what *really* happens.

[stuff deleted]

Quote:>Now, most UNIX systems have *some* history that dates back to a VAX.
>Even if your particular kernel has no VAX-specific code in its
>ancestry, it probably has some VAX-influenced code.  One of these
>influences is that lseek must accept `negative' offsets for seeks on
>/dev/kmem.  Some kernels implement this by allowing negative seeks only
>on the corresponding character major device; others allow it only on
>all character devices; still others (such as 4.4BSD) eliminate all the
>special-casing and just plain allow it.

I see, thanks for epxlaining why all this is.
The manpages about lseek(2v) for SunOS 4.1.1 do say the following under Errors:

     EINVAL         whence is not a proper value.

                    The seek operation would result in an illegal
                    file  offset value for the file (for example,
                    a negative file offset for a file other  than
                    a character special file).

So this confirms your explanation. Apparently SunOS allows all character devices
to have negative offsets.
The problem stil remains though: How to tell the difference between a succesfull
seek to position -1 and an error?

Quote:>None of this helps any if you have a system that misbehaves when using
>negative offsets, but to fix that, you must have kernel source.

The console driver misbehaves by not displaying stuff at negative offsets.
Unfortunately, I do not think the system administrators will allow me to hack
the kernel to fix this problem. :)

Vincent.
--


        Dennis Ritchie when born           FidoNet  : 2:281/202.15
                                           NeST     : 90:500/202.15

 
 
 

LSeek Weirdness or My Weirdness?

Post by Lawrence Kir » Sun, 07 Nov 1993 05:21:48




>>Of course there is:
>>       lseek(fd, 0L, 0);
>>       errno = 0;
>>       off = lseek(fd, -1L, 1);
>>       if (off == -1 && errno != 0)
>>               perror("lseek");
>>       else
>>               /* good */

>I'm afraid that won't work, because errno is not cleared on succesfull calls,

Which is why the code clears it manually before the call. However I don't
think that in principle a call can't set errno to != 0 even if it returns
successfully (this might happen if the call makes use of several other calls
internally where it migh recover from the failure of one of them).

-----------------------------------------


-----------------------------------------

 
 
 

LSeek Weirdness or My Weirdness?

Post by Casper H.S. D » Mon, 08 Nov 1993 20:42:55



>Which is why the code clears it manually before the call. However I don't
>think that in principle a call can't set errno to != 0 even if it returns
>successfully (this might happen if the call makes use of several other calls
>internally where it migh recover from the failure of one of them).

Function calls that allow -1 as a valid return value should promise not
alter errno on valid return.  This is usually stated in the manual
page (e.g., ptrace).

Casper

 
 
 

LSeek Weirdness or My Weirdness?

Post by Joe Foster of Bo » Mon, 08 Nov 1993 14:51:42



: >Of course there is:
: >  lseek(fd, 0L, 0);
: >  errno = 0;
        ^^^^^^^^^^
: >  off = lseek(fd, -1L, 1);
: >  if (off == -1 && errno != 0)
: >          perror("lseek");
: >  else
: >          /* good */

: I'm afraid that won't work, because errno is not cleared on succesfull calls,
: so you may be looking at an old returncode from a previous systemcall.
: Here's an excerpt from the SunOS 4.1.1 manual page intro(2):

However, the code above does explicitly clear errno.

--

WARNING: I cannot be held responsible for the above        They're   coming  to
because  my cats have  apparently  learned to type.        take me away, ha ha!

 
 
 

LSeek Weirdness or My Weirdness?

Post by Vincent Partingt » Tue, 09 Nov 1993 21:50:30



Quote:>: >Of course there is:
>: >      lseek(fd, 0L, 0);
>: >      errno = 0;
>        ^^^^^^^^^^
>: >      off = lseek(fd, -1L, 1);
>: >      if (off == -1 && errno != 0)
>: >              perror("lseek");
>: >      else
>: >              /* good */
>: I'm afraid that won't work, because errno is not cleared on succesfull calls,
>: so you may be looking at an old returncode from a previous systemcall.
>: Here's an excerpt from the SunOS 4.1.1 manual page intro(2):
>However, the code above does explicitly clear errno.

Yes, I forgot that. I pressed 'send' too fast. I should check my postings
more carefully.

Vincent.
--


        Dennis Ritchie when born           FidoNet  : 2:281/202.15
                                           NeST     : 90:500/202.15

 
 
 

LSeek Weirdness or My Weirdness?

Post by Peter Poorm » Wed, 10 Nov 1993 02:23:03



Quote:>However, the code above does explicitly clear errno.

True, but it still isn't safe.

The POSIX.1 standard says:

     "The value of [errno] shall be defined only after a call to a function
      for which it is explicitly stated to be set, and until it is changed
      by the next function call.  The variable errno should be only examined
      when it is indicated to be valid  by a function's return value."

      (Page 37, section 2.5, "Error Numbers".)

Note the word "defined".  This means that the value is indeterminate after
a function call that is not documented as explicitly setting it's value.
(Such as an open() call that suceeds.)  The standard does not require the
function to leave errno unaltered.

There's a reason for this.  It's common to implement library routines by
calling other library routines that are also visible to applications that
call the library.  If these internal calls return errors (as they often do),
then errno will be altered.  The value of errno is changed by the original
function call, but in an undefined way.

-- Pete Poorman

 
 
 

LSeek Weirdness or My Weirdness?

Post by Christopher Philli » Wed, 10 Nov 1993 08:25:00




>>However, the code above does explicitly clear errno.

>True, but it still isn't safe.

>The POSIX.1 standard says:

>     "The value of [errno] shall be defined only after a call to a function
>      for which it is explicitly stated to be set, and until it is changed
>      by the next function call.  The variable errno should be only examined
>      when it is indicated to be valid  by a function's return value."

>      (Page 37, section 2.5, "Error Numbers".)

Aren't there functions ``for which it [errno] is explicitly stated
to remain unchanged'' like readdir when it returns NULL because the end
of the directory has been reached?  Are there others?

Chris

 
 
 

LSeek Weirdness or My Weirdness?

Post by Lawrence Kir » Wed, 10 Nov 1993 22:02:45



>Function calls that allow -1 as a valid return value should promise not
>alter errno on valid return.  This is usually stated in the manual
>page (e.g., ptrace).

I don't think functions are in general required to do this (e.g. by POSIX)
so you shouldn't assume it in code.

-----------------------------------------


-----------------------------------------

 
 
 

LSeek Weirdness or My Weirdness?

Post by Casper H.S. D » Wed, 10 Nov 1993 23:39:38




>>Function calls that allow -1 as a valid return value should promise not
>>alter errno on valid return.  This is usually stated in the manual
>>page (e.g., ptrace).
>I don't think functions are in general required to do this (e.g. by POSIX)
>so you shouldn't assume it in code.

Functions in general do not return non-error -1s.
Functions that can return non-error -1 values should not
touch errno when they return a non-error -1.  That
what I said (well, meant to say).

Casper

 
 
 

LSeek Weirdness or My Weirdness?

Post by Christoph Badu » Thu, 11 Nov 1993 23:35:06



Quote:>Which is why the code clears it manually before the call. However I don't
>think that in principle a call can't set errno to != 0 even if it returns
>successfully (this might happen if the call makes use of several other calls
>internally where it migh recover from the failure of one of them).

In the general you're right, a call to some random function can of
course set errno != 0 and return successfully, fopen being one of the
best known ones.

However, this discussion was about how one could determine if the
lseek *system call* on *Unix* returned -1L as a legal file offset.
Therefore I felt that the following unstated assumption was safe:
lseek is a system call that doesn't make multiple internal calls and
sets errno !=0 only on failure.

--

Auf Chroma bestimmen die Frauen?  Das ist unglaublich!
                                        -- Cliff Alistair McLane, Orion VIII

 
 
 

LSeek Weirdness or My Weirdness?

Post by Christoph Badu » Thu, 11 Nov 1993 23:54:16


The problem is to figure out if a -1 return value from lseek(2)
indicates an error or a valid file offset.



>>However, the code above does explicitly clear errno.
>True, but it still isn't safe.

I disagree.

Quote:>The POSIX.1 standard says:

What the standard says is largely irrelevant in this case, because
either the implementation doesn't support negative file offsets (in
that case a return value of -1 *always* indicates an error and hence
errno is set) or the implementation supports negative file offsets and
therefore must provide a way to distinguish a file offset of -1 from
an error indication.  The only possible ways of doing this are to
either clear errno when the offset is -1 or to not modify errno if the
offset is -1.

You'll notice that my code copes correctly with both cases.

--

Auf Chroma bestimmen die Frauen?  Das ist unglaublich!
                                        -- Cliff Alistair McLane, Orion VIII

 
 
 

1. internal network weirdness

Ok, could use some help.

I have a RH6 box masqing my internal lan on a RR cable modem, 2 nic
setup.

All of a sudden when I ssh to the firewall/masq box from internally, my
lan i.p.'s show up as names that I have not assigned. here is output of
my "last". you can see that all of a sudden one day my int. i.p.'s start
showing up as craft and paulbentivegna.columbus.rr.com. What the hell?
These logins are all via ssh, which is the only "service" running on
this machine.

Everything else is blocked/disabled, and I am running the "strict"
ruleset from Trinity, so I have a hard time believing the machine is
being manipulated, although I guess ssh could be intercepted.

Any ideas? Have I been compromised? How could my internal boxes pick up
names I did not assign? They do have names and those are not what is
showing up!

Craft is actually my internal Linux box named beezus 192.168.1.5. and
paul.... is my NT laptop 192.168.1.2.

user1    pts/0        craft.columbus.r Sat Nov 20 20:41 - crash  (00:17)

user1    pts/0        craft.columbus.r Sat Nov 20 20:23 - 20:27  (00:04)

root     pts/0        craft.columbus.r Sat Nov 20 16:24 - 16:34  (00:09)

user1    pts/0        craft.columbus.r Sat Nov 20 16:12 - 16:12  (00:00)

user1    pts/0        craft.columbus.r Sat Nov 20 16:09 - 16:12  (00:02)

user1   pts/0        craft.columbus.r Sat Nov 20 16:07 - 16:08  (00:01)
user1   pts/0        craft.columbus.r Sat Nov 20 15:13 - 15:35  (00:21)
user1    pts/0        craft.columbus.r Sat Nov 20 14:53 - 15:12  (00:19)

root     pts/0        paulbentivegna.c Sat Nov 20 14:40 - 14:50  (00:09)

user1    pts/0        paulbentivegna.c Sat Nov 20 14:36 - 14:39  (00:02)

root     pts/0        worki.p. adress   Thu Nov 18 13:07 - 13:09
(00:01)
root     pts/0        192.168.1.5      Wed Nov 17 17:54 - 17:59  (00:04)

root     pts/0        192.168.1.5      Sun Nov 14 14:50 - 14:50  (00:00)

root     pts/0        192.168.1.5      Sat Nov 13 19:10 - 19:16  (00:05)

root     pts/0        192.168.1.5      Sat Nov 13 12:28 - 12:29  (00:00)

root     pts/0        192.168.1.5      Fri Nov 12 21:29 - 21:30  (00:01)

user1   pts/0        192.168.1.2      Thu Nov 11 21:10 - 21:11  (00:00)

2. iptables logging

3. xconsole / xterm -C weirdness

4. Directory Disappearing

5. Weirdness with PS/2 mouse and 3-button emulation

6. unix with windows?

7. 2.5.46 and make menuconfig weirdness

8. Help w/ UMAX C600 and YellowDog Linux

9. Please help - swap-space map bad / swap_duplicate weirdness

10. bash PATH weirdness

11. STB Nitro 3D weirdness

12. Extreme weirdness with RTS/CTS?

13. Regular expression weirdness with upper and lower case