Bug 17044 - Problem with shmat
Problem with shmat
Status: CLOSED WORKSFORME
Product: Red Hat Linux
Classification: Retired
Component: kernel (Show other bugs)
7.1
ia64 Linux
high Severity high
: ---
: ---
Assigned To: Michael K. Johnson
:
Depends On:
Blocks:
  Show dependency treegraph
 
Reported: 2000-08-28 12:31 EDT by Sunil Srivastava
Modified: 2008-05-01 11:37 EDT (History)
0 users

See Also:
Fixed In Version:
Doc Type: Bug Fix
Doc Text:
Story Points: ---
Clone Of:
Environment:
Last Closed: 2002-12-15 22:46:31 EST
Type: ---
Regression: ---
Mount Type: ---
Documentation: ---
CRM:
Verified Versions:
Category: ---
oVirt Team: ---
RHEL 7.3 requirements from Atomic Host:
Cloudforms Team: ---


Attachments (Terms of Use)

  None (edit)
Description Sunil Srivastava 2000-08-28 12:31:11 EDT
The following test program illustrates the problem.
The second call to shmat() fails on Solaris, HPUX, OSF1, 32-bit linux, and 
AIX.
Also fails on the trillian OS - (2.3.35).

However, it (incorrectly?) succeeds on trillian2 (Redhat 2.4.0-0.8smp).

/*************************************/
#include <stdio.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/shm.h>

main() {
    size_t sz1 = 32768, sz2 = 16384;
    char *addr1, *addr2;
    int id1, id2;

    id1 = shmget(IPC_PRIVATE, sz1, IPC_CREAT | 0664);
    id2 = shmget(IPC_PRIVATE, sz2, IPC_CREAT | 0664);

    addr1 = shmat(id1, 0, SHM_RND);

    /* This call fails on all platforms except Redhat 2.4.0-0.8smp */
    addr2 = addr1 + sz2;
    addr2 = shmat(id2, addr2, SHM_RND);

    shmdt(addr2);
    /* Now only the first 16k at addr1 is valid. */
    /* Second half of segment id1 has been unmapped !! */

}
Comment 1 David Mason 2000-08-28 12:37:47 EDT
This is a kernel bug - perhaps about IA64 (or glibc) - not a memprof bug -
reassigning
Comment 2 Michael K. Johnson 2000-08-28 14:52:53 EDT
Whether or not it fails is dependant on page size, alignment, etc.
There is not enough information here to designate this a bug.
Comment 3 Sunil Srivastava 2000-09-06 19:00:32 EDT
I dont think this has anything to do with page size, alignment, or shared 
memory block sizes.
The test case is a highly simplified example of code that has been ported to a 
wide variety of platforms.

In all other cases, the shmat() call fails if the specified address is inside 
another already attached segment.

The segment sizes were chosen to be a multiple of SHMLBA on all test systems.
Note that the test case uses SHM_RND.


#include <stdio.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/shm.h>

main() {
    size_t sz1 = 32768, sz2 = 16384;
    char *addr1, *addr2;
    int id1, id2;

    id1 = shmget(IPC_PRIVATE, sz1, IPC_CREAT | 0664);
    id2 = shmget(IPC_PRIVATE, sz2, IPC_CREAT | 0664);

    addr1 = shmat(id1, 0, SHM_RND);

    /* Try to attach segment 2 in the middle of segment 1 */
    /* This next call fails on all platforms except Redhat 2.4.0-0.8smp */
    addr2 = addr1 + sz2;
    addr2 = shmat(id2, addr2, SHM_RND);

    shmdt(addr2);
    /* Now only the first 16k at addr1 is valid. */
    /* Second half of segment id1 has been unmapped !! */

}

Comment 4 Alan Cox 2000-09-15 13:51:41 EDT
I can't find anything in SuS that says the Linux behaviour is a bug. Reading the
specifications I would say that it appears both results are legal. 2.4test seems
to have allowed the overlapping mappings as a lucky fallout of the more flexible
shm code now used.
Comment 5 Sunil Srivastava 2000-09-15 14:06:19 EDT
OK, the spec may allow it.
Are you saying that this will continue to operate differently from previous 
RedHat versions and virtually every other Unix-like platform in the world ?
Comment 6 Alan Cox 2000-09-16 17:15:56 EDT
I think you should expect all Linux 2.4 kernels to show this behaviour. SYS5 SHM
is now implemeted atop of posix shared memory and this is one of its side
effects
Comment 7 Sunil Srivastava 2000-10-02 13:43:07 EDT
We still believe there is a problem with either shmat() or shmdt() when
the attach address is specified.

The following snippet illustrates the problem.
It core dumps in printf() after calling shmdt() with a valid address returned 
by shmat().

#include <stdio.h>
#include <sys/types.h>
#include <sys/shm.h>

main() {
    void *addr, *addr2;
    unsigned long a1, a2;
    int id;
    size_t size = 512*1024;

    id = shmget(IPC_PRIVATE, size, IPC_CREAT | 0666);
    if (id == -1)
        goto FAIL2;

    /* Get the default attach address */
    addr = shmat(id, (void *)0, 0666 | SHM_RND);
    if (addr == (void *)-1)
        goto FAIL;
    if (shmdt(addr))
        goto FAIL;

    /* Get the address assigned by shmat for (default-1) */
    a1 = (unsigned long) addr;
    addr2 = shmat(id, (void *)(a1 - 1), 0666 | SHM_RND);
    if (addr2 == (void *)-1)
        goto FAIL;

    /* Here's the bug.
    ** If we don't call shmdt() we won't core. */
    if (shmdt(addr2))
        goto FAIL;

    /* here comes a core dump ... */
    printf("%s\n", "Success !");

    exit(0);

FAIL:
shmctl(id, IPC_RMID, 0);
FAIL2:
printf("Something wrong here ...\n");
exit(1);
}
Comment 8 Alan Cox 2002-12-15 22:46:31 EST
Works for me with current kernels

Note You need to log in before you can comment on or make changes to this bug.