man-pages/man2/modify_ldt.2.html
2021-03-31 01:06:50 +01:00

315 lines
6.8 KiB
HTML

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<HTML><HEAD><TITLE>Man page of MODIFY_LDT</TITLE>
</HEAD><BODY>
<H1>MODIFY_LDT</H1>
Section: Linux Programmer's Manual (2)<BR>Updated: 2020-02-09<BR><A HREF="#index">Index</A>
<A HREF="/cgi-bin/man/man2html">Return to Main Contents</A><HR>
<A NAME="lbAB">&nbsp;</A>
<H2>NAME</H2>
modify_ldt - get or set a per-process LDT entry
<A NAME="lbAC">&nbsp;</A>
<H2>SYNOPSIS</H2>
<PRE>
<B>#include &lt;<A HREF="file:///usr/include/sys/types.h">sys/types.h</A>&gt;</B>
<B>int modify_ldt(int </B><I>func</I><B>, void *</B><I>ptr</I><B>, unsigned long </B><I>bytecount</I><B>);</B>
</PRE>
<P>
<I>Note</I>:
There is no glibc wrapper for this system call; see NOTES.
<A NAME="lbAD">&nbsp;</A>
<H2>DESCRIPTION</H2>
<B>modify_ldt</B>()
reads or writes the local descriptor table (LDT) for a process.
The LDT
is an array of segment descriptors that can be referenced by user code.
Linux allows processes to configure a per-process (actually per-mm) LDT.
For more information about the LDT, see the Intel Software Developer's
Manual or the AMD Architecture Programming Manual.
<P>
When
<I>func</I>
is 0,
<B>modify_ldt</B>()
reads the LDT into the memory pointed to by
<I>ptr</I>.
The number of bytes read is the smaller of
<I>bytecount</I>
and the actual size of the LDT, although the kernel may act as though
the LDT is padded with additional trailing zero bytes.
On success,
<B>modify_ldt</B>()
will return the number of bytes read.
<P>
When
<I>func</I>
is 1 or 0x11,
<B>modify_ldt</B>()
modifies the LDT entry indicated by
<I>ptr-&gt;entry_number</I>.
<I>ptr</I>
points to a
<I>user_desc</I>
structure
and
<I>bytecount</I>
must equal the size of this structure.
<P>
The
<I>user_desc</I>
structure is defined in <I>&lt;<A HREF="file:///usr/include/asm/ldt.h">asm/ldt.h</A>&gt;</I> as:
<P>
struct user_desc {
<BR>&nbsp;&nbsp;&nbsp;&nbsp;unsigned&nbsp;int&nbsp;&nbsp;entry_number;
<BR>&nbsp;&nbsp;&nbsp;&nbsp;unsigned&nbsp;int&nbsp;&nbsp;base_addr;
<BR>&nbsp;&nbsp;&nbsp;&nbsp;unsigned&nbsp;int&nbsp;&nbsp;limit;
<BR>&nbsp;&nbsp;&nbsp;&nbsp;unsigned&nbsp;int&nbsp;&nbsp;seg_32bit:1;
<BR>&nbsp;&nbsp;&nbsp;&nbsp;unsigned&nbsp;int&nbsp;&nbsp;contents:2;
<BR>&nbsp;&nbsp;&nbsp;&nbsp;unsigned&nbsp;int&nbsp;&nbsp;read_exec_only:1;
<BR>&nbsp;&nbsp;&nbsp;&nbsp;unsigned&nbsp;int&nbsp;&nbsp;limit_in_pages:1;
<BR>&nbsp;&nbsp;&nbsp;&nbsp;unsigned&nbsp;int&nbsp;&nbsp;seg_not_present:1;
<BR>&nbsp;&nbsp;&nbsp;&nbsp;unsigned&nbsp;int&nbsp;&nbsp;useable:1;
};
<P>
In Linux 2.4 and earlier, this structure was named
<I>modify_ldt_ldt_s</I>.
<P>
The
<I>contents</I>
field is the segment type (data, expand-down data, non-conforming code, or
conforming code).
The other fields match their descriptions in the CPU manual, although
<B>modify_ldt</B>()
cannot set the hardware-defined &quot;accessed&quot; bit described in the CPU manual.
<P>
A
<I>user_desc</I>
is considered &quot;empty&quot; if
<I>read_exec_only</I>
and
<I>seg_not_present</I>
are set to 1 and all of the other fields are 0.
An LDT entry can be cleared by setting it to an &quot;empty&quot;
<I>user_desc</I>
or, if
<I>func</I>
is 1, by setting both
<I>base</I>
and
<I>limit</I>
to 0.
<P>
A conforming code segment (i.e., one with
<I>contents==3</I>)
will be rejected if
<I>func</I>
is 1 or if
<I>seg_not_present</I>
is 0.
<P>
When
<I>func</I>
is 2,
<B>modify_ldt</B>()
will read zeros.
This appears to be a leftover from Linux 2.4.
<A NAME="lbAE">&nbsp;</A>
<H2>RETURN VALUE</H2>
On success,
<B>modify_ldt</B>()
returns either the actual number of bytes read (for reading)
or 0 (for writing).
On failure,
<B>modify_ldt</B>()
returns -1 and sets
<I>errno</I>
to indicate the error.
<A NAME="lbAF">&nbsp;</A>
<H2>ERRORS</H2>
<DL COMPACT>
<DT id="1"><B>EFAULT</B>
<DD>
<I>ptr</I>
points outside the address space.
<DT id="2"><B>EINVAL</B>
<DD>
<I>ptr</I>
is 0,
or
<I>func</I>
is 1 and
<I>bytecount</I>
is not equal to the size of the structure
<I>user_desc</I>,
or
<I>func</I>
is 1 or 0x11 and the new LDT entry has invalid values.
<DT id="3"><B>ENOSYS</B>
<DD>
<I>func</I>
is neither 0, 1, 2, nor 0x11.
</DL>
<A NAME="lbAG">&nbsp;</A>
<H2>CONFORMING TO</H2>
This call is Linux-specific and should not be used in programs intended
to be portable.
<A NAME="lbAH">&nbsp;</A>
<H2>NOTES</H2>
Glibc does not provide a wrapper for this system call; call it using
<B><A HREF="/cgi-bin/man/man2html?2+syscall">syscall</A></B>(2).
<P>
<B>modify_ldt</B>()
should not be used for thread-local storage, as it slows down context
switches and only supports a limited number of threads.
Threading libraries should use
<B><A HREF="/cgi-bin/man/man2html?2+set_thread_area">set_thread_area</A></B>(2)
or
<B><A HREF="/cgi-bin/man/man2html?2+arch_prctl">arch_prctl</A></B>(2)
instead, except on extremely old kernels that do not support those system
calls.
<P>
The normal use for
<B>modify_ldt</B>()
is to run legacy 16-bit or segmented 32-bit code.
Not all kernels allow 16-bit segments to be installed, however.
<P>
Even on 64-bit kernels,
<B>modify_ldt</B>()
cannot be used to create a long mode (i.e., 64-bit) code segment.
The undocumented field &quot;lm&quot; in
<I>user_desc</I>
is not useful, and, despite its name,
does not result in a long mode segment.
<A NAME="lbAI">&nbsp;</A>
<H2>BUGS</H2>
On 64-bit kernels before Linux 3.19,
setting the &quot;lm&quot; bit in
<I>user_desc</I>
prevents the descriptor from being considered empty.
Keep in mind that the
&quot;lm&quot; bit does not exist in the 32-bit headers, but these buggy kernels
will still notice the bit even when set in a 32-bit process.
<A NAME="lbAJ">&nbsp;</A>
<H2>SEE ALSO</H2>
<B><A HREF="/cgi-bin/man/man2html?2+arch_prctl">arch_prctl</A></B>(2),
<B><A HREF="/cgi-bin/man/man2html?2+set_thread_area">set_thread_area</A></B>(2),
<B><A HREF="/cgi-bin/man/man2html?2+vm86">vm86</A></B>(2)
<A NAME="lbAK">&nbsp;</A>
<H2>COLOPHON</H2>
This page is part of release 5.05 of the Linux
<I>man-pages</I>
project.
A description of the project,
information about reporting bugs,
and the latest version of this page,
can be found at
<A HREF="https://www.kernel.org/doc/man-pages/.">https://www.kernel.org/doc/man-pages/.</A>
<P>
<HR>
<A NAME="index">&nbsp;</A><H2>Index</H2>
<DL>
<DT id="4"><A HREF="#lbAB">NAME</A><DD>
<DT id="5"><A HREF="#lbAC">SYNOPSIS</A><DD>
<DT id="6"><A HREF="#lbAD">DESCRIPTION</A><DD>
<DT id="7"><A HREF="#lbAE">RETURN VALUE</A><DD>
<DT id="8"><A HREF="#lbAF">ERRORS</A><DD>
<DT id="9"><A HREF="#lbAG">CONFORMING TO</A><DD>
<DT id="10"><A HREF="#lbAH">NOTES</A><DD>
<DT id="11"><A HREF="#lbAI">BUGS</A><DD>
<DT id="12"><A HREF="#lbAJ">SEE ALSO</A><DD>
<DT id="13"><A HREF="#lbAK">COLOPHON</A><DD>
</DL>
<HR>
This document was created by
<A HREF="/cgi-bin/man/man2html">man2html</A>,
using the manual pages.<BR>
Time: 00:05:33 GMT, March 31, 2021
</BODY>
</HTML>